2015-12-08 15:45:58 -07:00
|
|
|
/*
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
|
|
|
|
/*
|
|
|
|
|
Copyright (c) 2008 Eliot Dresselhaus
|
|
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining
|
|
|
|
|
a copy of this software and associated documentation files (the
|
|
|
|
|
"Software"), to deal in the Software without restriction, including
|
|
|
|
|
without limitation the rights to use, copy, modify, merge, publish,
|
|
|
|
|
distribute, sublicense, and/or sell copies of the Software, and to
|
|
|
|
|
permit persons to whom the Software is furnished to do so, subject to
|
|
|
|
|
the following conditions:
|
|
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be
|
|
|
|
|
included in all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
|
|
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
|
|
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
|
|
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
|
|
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
|
|
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
|
|
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <vppinfra/elf.h>
|
|
|
|
|
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
|
|
|
|
|
#ifndef CLIB_UNIX
|
|
|
|
|
#error "unix only"
|
|
|
|
|
#endif
|
|
|
|
|
|
2016-08-15 11:12:27 -04:00
|
|
|
static clib_error_t *
|
|
|
|
|
elf_set_interpreter (elf_main_t * em, char *interp)
|
2015-12-08 15:45:58 -07:00
|
|
|
{
|
2016-08-15 11:12:27 -04:00
|
|
|
elf_segment_t *g;
|
|
|
|
|
elf_section_t *s;
|
|
|
|
|
clib_error_t *error;
|
2015-12-08 15:45:58 -07:00
|
|
|
|
|
|
|
|
vec_foreach (g, em->segments)
|
2016-08-15 11:12:27 -04:00
|
|
|
{
|
|
|
|
|
if (g->header.type == ELF_SEGMENT_INTERP)
|
|
|
|
|
break;
|
|
|
|
|
}
|
2015-12-08 15:45:58 -07:00
|
|
|
|
|
|
|
|
if (g >= vec_end (em->segments))
|
|
|
|
|
return clib_error_return (0, "interpreter not found");
|
|
|
|
|
|
|
|
|
|
if (g->header.memory_size < 1 + strlen (interp))
|
2016-08-15 11:12:27 -04:00
|
|
|
return clib_error_return (0,
|
|
|
|
|
"given interpreter does not fit; must be less than %d bytes (`%s' given)",
|
2015-12-08 15:45:58 -07:00
|
|
|
g->header.memory_size, interp);
|
|
|
|
|
|
2016-08-15 11:12:27 -04:00
|
|
|
error =
|
|
|
|
|
elf_get_section_by_start_address (em, g->header.virtual_address, &s);
|
2015-12-08 15:45:58 -07:00
|
|
|
if (error)
|
|
|
|
|
return error;
|
|
|
|
|
|
|
|
|
|
/* Put in new null terminated string. */
|
2018-10-17 10:38:51 -04:00
|
|
|
clib_memset (s->contents, 0, vec_len (s->contents));
|
2016-03-13 02:22:06 +01:00
|
|
|
clib_memcpy (s->contents, interp, strlen (interp));
|
2015-12-08 15:45:58 -07:00
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
delete_dynamic_rpath_entries_from_section (elf_main_t * em, elf_section_t * s)
|
|
|
|
|
{
|
2016-08-15 11:12:27 -04:00
|
|
|
elf64_dynamic_entry_t *e;
|
|
|
|
|
elf64_dynamic_entry_t *new_es = 0;
|
2015-12-08 15:45:58 -07:00
|
|
|
|
|
|
|
|
vec_foreach (e, em->dynamic_entries)
|
2016-08-15 11:12:27 -04:00
|
|
|
{
|
|
|
|
|
switch (e->type)
|
|
|
|
|
{
|
|
|
|
|
case ELF_DYNAMIC_ENTRY_RPATH:
|
|
|
|
|
case ELF_DYNAMIC_ENTRY_RUN_PATH:
|
|
|
|
|
break;
|
2015-12-08 15:45:58 -07:00
|
|
|
|
2016-08-15 11:12:27 -04:00
|
|
|
default:
|
|
|
|
|
vec_add1 (new_es, e[0]);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-12-08 15:45:58 -07:00
|
|
|
|
|
|
|
|
/* Pad so as to keep section size constant. */
|
|
|
|
|
{
|
|
|
|
|
elf64_dynamic_entry_t e_end;
|
|
|
|
|
e_end.type = ELF_DYNAMIC_ENTRY_END;
|
|
|
|
|
e_end.data = 0;
|
|
|
|
|
while (vec_len (new_es) < vec_len (em->dynamic_entries))
|
|
|
|
|
vec_add1 (new_es, e_end);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
elf_set_dynamic_entries (em);
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-15 11:12:27 -04:00
|
|
|
static void
|
|
|
|
|
elf_delete_dynamic_rpath_entries (elf_main_t * em)
|
2015-12-08 15:45:58 -07:00
|
|
|
{
|
2016-08-15 11:12:27 -04:00
|
|
|
elf_section_t *s;
|
2015-12-08 15:45:58 -07:00
|
|
|
|
|
|
|
|
vec_foreach (s, em->sections)
|
2016-08-15 11:12:27 -04:00
|
|
|
{
|
|
|
|
|
switch (s->header.type)
|
|
|
|
|
{
|
|
|
|
|
case ELF_SECTION_DYNAMIC:
|
|
|
|
|
delete_dynamic_rpath_entries_from_section (em, s);
|
|
|
|
|
break;
|
2015-12-08 15:45:58 -07:00
|
|
|
|
2016-08-15 11:12:27 -04:00
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-12-08 15:45:58 -07:00
|
|
|
}
|
|
|
|
|
|
2016-08-15 11:12:27 -04:00
|
|
|
typedef struct
|
|
|
|
|
{
|
2015-12-08 15:45:58 -07:00
|
|
|
elf_main_t elf_main;
|
2016-08-15 11:12:27 -04:00
|
|
|
char *input_file;
|
|
|
|
|
char *output_file;
|
|
|
|
|
char *set_interpreter;
|
2015-12-08 15:45:58 -07:00
|
|
|
int verbose;
|
|
|
|
|
} elf_test_main_t;
|
|
|
|
|
|
2016-08-15 11:12:27 -04:00
|
|
|
int
|
|
|
|
|
main (int argc, char *argv[])
|
2015-12-08 15:45:58 -07:00
|
|
|
{
|
2016-08-15 11:12:27 -04:00
|
|
|
elf_test_main_t _tm, *tm = &_tm;
|
|
|
|
|
elf_main_t *em = &tm->elf_main;
|
2015-12-08 15:45:58 -07:00
|
|
|
unformat_input_t i;
|
2016-08-15 11:12:27 -04:00
|
|
|
clib_error_t *error = 0;
|
2015-12-08 15:45:58 -07:00
|
|
|
|
2018-10-17 10:38:51 -04:00
|
|
|
clib_memset (tm, 0, sizeof (tm[0]));
|
2015-12-08 15:45:58 -07:00
|
|
|
|
|
|
|
|
unformat_init_command_line (&i, argv);
|
|
|
|
|
while (unformat_check_input (&i) != UNFORMAT_END_OF_INPUT)
|
|
|
|
|
{
|
|
|
|
|
if (unformat (&i, "in %s", &tm->input_file))
|
|
|
|
|
;
|
|
|
|
|
else if (unformat (&i, "out %s", &tm->output_file))
|
|
|
|
|
;
|
|
|
|
|
else if (unformat (&i, "set-interpreter %s", &tm->set_interpreter))
|
|
|
|
|
;
|
|
|
|
|
else if (unformat (&i, "verbose"))
|
|
|
|
|
tm->verbose = ~0;
|
|
|
|
|
else if (unformat (&i, "verbose-symbols"))
|
|
|
|
|
tm->verbose |= FORMAT_ELF_MAIN_SYMBOLS;
|
|
|
|
|
else if (unformat (&i, "verbose-relocations"))
|
|
|
|
|
tm->verbose |= FORMAT_ELF_MAIN_RELOCATIONS;
|
|
|
|
|
else if (unformat (&i, "verbose-dynamic"))
|
|
|
|
|
tm->verbose |= FORMAT_ELF_MAIN_DYNAMIC;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
error = unformat_parse_error (&i);
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-13 00:05:27 +02:00
|
|
|
if (!tm->input_file)
|
|
|
|
|
{
|
2016-08-15 11:12:27 -04:00
|
|
|
clib_warning ("No input file! Using test_bihash_template");
|
2016-04-13 00:05:27 +02:00
|
|
|
tm->input_file = "test_bihash_template";
|
|
|
|
|
}
|
2015-12-08 15:45:58 -07:00
|
|
|
|
|
|
|
|
error = elf_read_file (em, tm->input_file);
|
|
|
|
|
if (error)
|
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
|
|
if (tm->set_interpreter)
|
|
|
|
|
{
|
2016-08-15 11:12:27 -04:00
|
|
|
clib_error_t *error = elf_set_interpreter (em, tm->set_interpreter);
|
2015-12-08 15:45:58 -07:00
|
|
|
if (error)
|
|
|
|
|
goto done;
|
|
|
|
|
elf_delete_dynamic_rpath_entries (em);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (tm->verbose)
|
|
|
|
|
fformat (stdout, "%U", format_elf_main, em, tm->verbose);
|
|
|
|
|
|
|
|
|
|
if (tm->output_file)
|
|
|
|
|
error = elf_write_file (em, tm->output_file);
|
|
|
|
|
|
|
|
|
|
elf_main_free (em);
|
|
|
|
|
|
2016-08-15 11:12:27 -04:00
|
|
|
done:
|
2015-12-08 15:45:58 -07:00
|
|
|
if (error)
|
|
|
|
|
{
|
|
|
|
|
clib_error_report (error);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2016-08-15 11:12:27 -04:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* fd.io coding-style-patch-verification: ON
|
|
|
|
|
*
|
|
|
|
|
* Local Variables:
|
|
|
|
|
* eval: (c-set-style "gnu")
|
|
|
|
|
* End:
|
|
|
|
|
*/
|