<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2015 Cisco and/or its affiliates.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>io.fd.hc2vpp.common</groupId>
<artifactId>api-parent</artifactId>
<version>1.18.01-SNAPSHOT</version>
<relativePath>../../common/api-parent</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>io.fd.hc2vpp.routing
@media only all and (prefers-color-scheme: dark) {
.highlight .hll { background-color: #49483e }
.highlight .c { color: #75715e } /* Comment */
.highlight .err { color: #960050; background-color: #1e0010 } /* Error */
.highlight .k { color: #66d9ef } /* Keyword */
.highlight .l { color: #ae81ff } /* Literal */
.highlight .n { color: #f8f8f2 } /* Name */
.highlight .o { color: #f92672 } /* Operator */
.highlight .p { color: #f8f8f2 } /* Punctuation */
.highlight .ch { color: #75715e } /* Comment.Hashbang */
.highlight .cm { color: #75715e } /* Comment.Multiline */
.highlight .cp { color: #75715e } /* Comment.Preproc */
.highlight .cpf { color: #75715e } /* Comment.PreprocFile */
.highlight .c1 { color: #75715e } /* Comment.Single */
.highlight .cs { color: #75715e } /* Comment.Special */
.highlight .gd { color: #f92672 } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gi { color: #a6e22e } /* Generic.Inserted */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #75715e } /* Generic.Subheading */
.highlight .kc { color: #66d9ef } /* Keyword.Constant */
.highlight .kd { color: #66d9ef } /* Keyword.Declaration */
.highlight .kn { color: #f92672 } /* Keyword.Namespace */
.highlight .kp { color: #66d9ef } /* Keyword.Pseudo */
.highlight .kr { color: #66d9ef } /* Keyword.Reserved */
.highlight .kt { color: #66d9ef } /* Keyword.Type */
.highlight .ld { color: #e6db74 } /* Literal.Date */
.highlight .m { color: #ae81ff } /* Literal.Number */
.highlight .s { color: #e6db74 } /* Literal.String */
.highlight .na { color: #a6e22e } /* Name.Attribute */
.highlight .nb { color: #f8f8f2 } /* Name.Builtin */
.highlight .nc { color: #a6e22e } /* Name.Class */
.highlight .no { color: #66d9ef } /* Name.Constant */
.highlight .nd { color: #a6e22e } /* Name.Decorator */
.highlight .ni { color: #f8f8f2 } /* Name.Entity */
.highlight .ne { color: #a6e22e } /* Name.Exception */
.highlight .nf { color: #a6e22e } /* Name.Function */
.highlight .nl { color: #f8f8f2 } /* Name.Label */
.highlight .nn { color: #f8f8f2 } /* Name.Namespace */
.highlight .nx { color: #a6e22e } /* Name.Other */
.highlight .py { color: #f8f8f2 } /* Name.Property */
.highlight .nt { color: #f92672 } /* Name.Tag */
.highlight .nv { color: #f8f8f2 } /* Name.Variable */
.highlight .ow { color: #f92672 } /* Operator.Word */
.highlight .w { color: #f8f8f2 } /* Text.Whitespace */
.highlight .mb { color: #ae81ff } /* Literal.Number.Bin */
.highlight .mf { color: #ae81ff } /* Literal.Number.Float */
.highlight .mh { color: #ae81ff } /* Literal.Number.Hex */
.highlight .mi { color: #ae81ff } /* Literal.Number.Integer */
.highlight .mo { color: #ae81ff } /* Literal.Number.Oct */
.highlight .sa { color: #e6db74 } /* Literal.String.Affix */
.highlight .sb { color: #e6db74 } /* Literal.String.Backtick */
.highlight .sc { color: #e6db74 } /* Literal.String.Char */
.highlight .dl { color: #e6db74 } /* Literal.String.Delimiter */
.highlight .sd { color: #e6db74 } /* Literal.String.Doc */
.highlight .s2 { color: #e6db74 } /* Literal.String.Double */
.highlight .se { color: #ae81ff } /* Literal.String.Escape */
.highlight .sh { color: #e6db74 } /* Literal.String.Heredoc */
.highlight .si { color: #e6db74 } /* Literal.String.Interpol */
.highlight .sx { color: #e6db74 } /* Literal.String.Other */
.highlight .sr { color: #e6db74 } /* Literal.String.Regex */
.highlight .s1 { color: #e6db74 } /* Literal.String.Single */
.highlight .ss { color: #e6db74 } /* Literal.String.Symbol */
.highlight .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #a6e22e } /* Name.Function.Magic */
.highlight .vc { color: #f8f8f2 } /* Name.Variable.Class */
.highlight .vg { color: #f8f8f2 } /* Name.Variable.Global */
.highlight .vi { color: #f8f8f2 } /* Name.Variable.Instance */
.highlight .vm { color: #f8f8f2 } /* Name.Variable.Magic */
.highlight .il { color: #ae81ff } /* Literal.Number.Integer.Long */
}
@media (prefers-color-scheme: light) {
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
}
/*
* Copyright (c) 2015 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <vppinfra/elf_clib.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
typedef struct
{
char **path;
} path_search_t;
always_inline void
path_search_free (path_search_t * p)
{
uword i;
for (i = 0; i < vec_len (p->path); i++)
vec_free (p->path[i]);
vec_free (p->path);
}
static char **
split_string (char *string, u8 delimiter)
{
char **result = 0;
char *p, *start, *s;
p = string;
while (1)
{
start = p;
while (*p != 0 && *p != delimiter)
p++;
s = 0;
vec_add (s, start, p - start);
vec_add1 (s, 0);
vec_add1 (result, s);
if (*p == 0)
break;
p++;
}
return result;
}
static int
file_exists_and_is_executable (char *dir, char *file)
{
char *path = (char *) format (0, "%s/%s%c", dir, file, 0);
struct stat s;
uword yes;
yes = (stat (path, &s) >= 0
&& S_ISREG (s.st_mode)
&& 0 != (s.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)));
vec_free (path);
return yes;
}
static char *
path_search (char *file)
{
path_search_t ps;
uword i;
char *result;
/* Relative or absolute path. */
if (file[0] == '.' || file[0] == '/')
return file;
if (getenv ("PATH") == 0)
return file;
ps.path = split_string (getenv ("PATH"), ':');
for (i = 0; i < vec_len (ps.path); i++)
if (file_exists_and_is_executable (ps.path[i], file))
break;
result = 0;
if (i < vec_len (ps.path))
result = (char *) format (0, "%s/%s%c", ps.path[i], file);
path_search_free (&ps);
return result;
}
static clib_error_t *
clib_elf_parse_file (clib_elf_main_t * cem,
char *file_name, void *link_address)
{
elf_main_t *em;
elf_section_t *s;
int fd;
struct stat fd_stat;
uword mmap_length = 0;
void *data = 0;
clib_error_t *error = 0;
vec_add2 (cem->elf_mains, em, 1);
fd = open (file_name, 0);
if (fd < 0)
{
error = clib_error_return_unix (0, "open `%s'", file_name);
goto done;
}
if (fstat (fd, &fd_stat) < 0)
{
error = clib_error_return_unix (0, "fstat `%s'", file_name);
goto done;
}
mmap_length = fd_stat.st_size;
data = mmap (0, mmap_length, PROT_READ, MAP_SHARED, fd, /* offset */ 0);
if (~pointer_to_uword (data) == 0)
{
error = clib_error_return_unix (0, "mmap `%s'", file_name);
goto done;
}
error = elf_parse (em, data, mmap_length);
if (error)
goto done;
/* Look for CLIB special sections. */
{
char *section_name_start = CLIB_ELF_SECTION_ADD_PREFIX ();
uword section_name_start_len = strlen (section_name_start);
vec_foreach (s, em->sections)
{
u8 *name = elf_section_name (em, s);
uword *p;
clib_elf_section_t *vs;
clib_elf_section_bounds_t *b;
/* Section name must begin with CLIB_ELF_SECTION key. */
if (strcmp ((char *) name, section_name_start))
continue;
name += section_name_start_len;
p = hash_get_mem (cem->section_by_name, name);
if (p)
vs = vec_elt_at_index (cem->sections, p[0]);
else
{
name = format (0, "%s%c", name, 0);
if (!cem->section_by_name)
cem->section_by_name = hash_create_string (0, sizeof (uword));
hash_set_mem (cem->section_by_name, name, vec_len (cem->sections));
vec_add2 (cem->sections, vs, 1);
vs->name = name;
}
vec_add2 (vs->bounds, b, 1);
b->lo = link_address + s->header.exec_address;
b->hi = b->lo + s->header.file_size;
}
}
/* Parse symbols for this file. */
{
elf_symbol_table_t *t;
elf64_symbol_t *s;
elf_parse_symbols (em);
vec_foreach (t, em->symbol_tables)
{
vec_foreach (s, t->symbols)
{
s->value += pointer_to_uword (link_address);
}
}
}
/* No need to keep section contents around. */
{
elf_section_t *s;
vec_foreach (s, em->sections)
{
if (s->header.type != ELF_SECTION_STRING_TABLE)
vec_free (s->contents);
}
}
done:
if (error)
elf_main_free (em);
if (fd >= 0)
close (fd);
if (data)
munmap (data, mmap_length);
return error;
}
#define __USE_GNU
#include <link.h>
static int
add_section (struct dl_phdr_info *info, size_t size, void *opaque)
{
clib_elf_main_t *cem = opaque;
clib_error_t *error;
char *name = (char *) info->dlpi_name;
void *addr = (void *) info->dlpi_addr;
uword is_main;
is_main = strlen (name) == 0;
if (is_main)
{
static int done;
/* Only do main program once. */
if (done++)
return 0;
name = path_search (cem->exec_path);
if (!name)
{
clib_error ("failed to find %s on PATH", cem->exec_path);
return 0;
}
addr = 0;
}
error = clib_elf_parse_file (cem, name, addr);
if (error)
clib_error_report (error);
if (is_main && name != cem->exec_path)
vec_free (name);
return 0;
}
static clib_elf_main_t clib_elf_main;
void
clib_elf_main_init (char *exec_path)
{
clib_elf_main_t *cem = &clib_elf_main;
cem->exec_path = exec_path;
dl_iterate_phdr (add_section, cem);
}
clib_elf_section_bounds_t *
clib_elf_get_section_bounds (char *name)
{
clib_elf_main_t *em = &clib_elf_main;
uword *p = hash_get (em->section_by_name, name);
return p ? vec_elt_at_index (em->sections, p[0])->bounds : 0;
}
static uword
symbol_by_address_or_name (char *by_name,
uword by_address, clib_elf_symbol_t * s)
{
clib_elf_main_t *cem = &clib_elf_main;
elf_main_t *em;
vec_foreach (em, cem->elf_mains)
{
elf_symbol_table_t *t;
s->elf_main_index = em - cem->elf_mains;
vec_foreach (t, em->symbol_tables)
{
s->symbol_table_index = t - em->symbol_tables;
if (by_name)
{
uword *p = hash_get (t->symbol_by_name, by_name);
if (p)
{
s->symbol = vec_elt (t->symbols, p[0]);
return 1;
}
}
else
{
elf64_symbol_t *x;
/* FIXME linear search. */
vec_foreach (x, t->symbols)
{
if (by_address >= x->value && by_address < x->value + x->size)
{
s->symbol = x[0];
return 1;
}
}
}
}
}
return 0;
}
uword
clib_elf_symbol_by_name (char *by_name, clib_elf_symbol_t * s)
{
return symbol_by_address_or_name (by_name, /* by_address */ 0, s);
}
uword
clib_elf_symbol_by_address (uword by_address, clib_elf_symbol_t * s)
{
return symbol_by_address_or_name ( /* by_name */ 0, by_address, s);
}
u8 *
format_clib_elf_symbol (u8 * s, va_list * args)
{
clib_elf_main_t *cem = &clib_elf_main;
clib_elf_symbol_t *sym = va_arg (*args, clib_elf_symbol_t *);
elf_main_t *em;
elf_symbol_table_t *t;
if (!sym)
/* Just print table headings. */
return format (s, "%U", format_elf_symbol, 0, 0, 0);
else
{
em = vec_elt_at_index (cem->elf_mains, sym->elf_main_index);
t = vec_elt_at_index (em->symbol_tables, sym->symbol_table_index);
return format (s, "%U", format_elf_symbol, em, t, &sym->symbol);
}
}
u8 *
format_clib_elf_symbol_with_address (u8 * s, va_list * args)
{
uword address = va_arg (*args, uword);
clib_elf_main_t *cem = &clib_elf_main;
clib_elf_symbol_t sym;
elf_main_t *em;
elf_symbol_table_t *t;
if (clib_elf_symbol_by_address (address, &sym))
{
em = vec_elt_at_index (cem->elf_mains, sym.elf_main_index);
t = vec_elt_at_index (em->symbol_tables, sym.symbol_table_index);
s = format (s, "%s + 0x%wx",
elf_symbol_name (t, &sym.symbol),
address - sym.symbol.value);
}
else
s = format (s, "0x%wx", address);
return s;
}
/*
* fd.io coding-style-patch-verification: ON
*
* Local Variables:
* eval: (c-set-style "gnu")
* End:
*/