FD.io VPP  v16.06
Vector Packet Processing
elf.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include <vppinfra/bitmap.h>
16 #include <vppinfra/byte_order.h>
17 #include <vppinfra/error.h>
18 #include <vppinfra/hash.h>
19 #include <vppinfra/vec.h>
20 #include <vppinfra/elf.h>
21 
22 always_inline void
24 {
26  h->file_type = elf_swap_u16 (em, h->file_type);
28 }
29 
30 always_inline void
32 {
33 #define _(t,f) n->f = clib_byte_swap_##t (n->f);
35 #undef _
36 }
37 
38 always_inline void
40 {
41 #define _(t,f) n->f = clib_byte_swap_##t (n->f);
43 #undef _
44 }
45 
47 elf_get_section_by_name (elf_main_t * em, char * section_name, elf_section_t ** result)
48 {
49  uword * p;
50 
51  p = hash_get_mem (em->section_by_name, section_name);
52  if (! p)
53  return clib_error_return (0, "no such section `%s'", section_name);
54 
55  *result = vec_elt_at_index (em->sections, p[0]);
56  return 0;
57 }
58 
61 {
62  uword * p = hash_get (em->section_by_start_address, start_address);
63  return p ? vec_elt_at_index (em->sections, p[0]) : 0;
64 }
65 
68 {
70  if (! s)
71  return clib_error_return (0, "no section with address 0x%wx", start_address);
72  *result = s;
73  return 0;
74 }
75 
76 static u8 *
77 format_elf_section_type (u8 * s, va_list * args)
78 {
79  elf_section_type_t type = va_arg (*args, elf_section_type_t);
80  char * t = 0;
81 
82  switch (type)
83  {
84 #define _(f,i) case ELF_SECTION_##f: t = #f; break;
86 #undef _
87  }
88 
89  if (! t)
90  s = format (s, "unknown 0x%x", type);
91  else
92  s = format (s, "%s", t);
93  return s;
94 }
95 
96 static u8 *
97 format_elf_section (u8 * s, va_list * args)
98 {
99  elf_main_t * em = va_arg (*args, elf_main_t *);
100  elf_section_t * es = va_arg (*args, elf_section_t *);
101  elf64_section_header_t * h = &es->header;
102 
103  if (! h)
104  return format (s, "%=40s%=10s%=20s%=8s%=16s%=16s%=16s",
105  "Name", "Index", "Type", "Size", "Align", "Address", "File offset");
106 
107  s = format (s, "%-40s%10d%=20U%8Lx%16d%16Lx %Lx-%Lx",
108  elf_section_name (em, es),
109  es->index,
110  format_elf_section_type, h->type,
111  h->file_size,
112  h->align,
113  h->exec_address,
114  h->file_offset, h->file_offset + h->file_size);
115 
116  if (h->flags != 0)
117  {
118 #define _(f,i) \
119  if (h->flags & ELF_SECTION_FLAG_##f) s = format (s, " %s", #f);
121 #undef _
122  }
123 
124  return s;
125 }
126 
127 static u8 *
128 format_elf_segment_type (u8 * s, va_list * args)
129 {
130  elf_segment_type_t type = va_arg (*args, elf_segment_type_t);
131  char * t = 0;
132 
133  switch (type)
134  {
135 #define _(f,i) case ELF_SEGMENT_##f: t = #f; break;
137 #undef _
138  }
139 
140  if (! t)
141  s = format (s, "unknown 0x%x", type);
142  else
143  s = format (s, "%s", t);
144  return s;
145 }
146 
147 static u8 *
148 format_elf_segment (u8 * s, va_list * args)
149 {
150  elf_segment_t * es = va_arg (*args, elf_segment_t *);
151  elf64_segment_header_t * h = &es->header;
152 
153  if (! h)
154  return format (s, "%=16s%=16s%=16s%=16s",
155  "Type", "Virt. Address", "Phys. Address", "Size");
156 
157  s = format (s, "%=16U%16Lx%16Lx%16Lx%16Lx",
158  format_elf_segment_type, h->type,
159  h->virtual_address,
160  h->physical_address,
161  h->memory_size,
162  h->file_offset);
163 
164  if (h->flags != 0)
165  {
166 #define _(f,i) \
167  if (h->flags & ELF_SEGMENT_FLAG_##f) s = format (s, " %s", #f);
169 #undef _
170  }
171 
172  return s;
173 }
174 
175 static u8 *
177 {
178  int bt = va_arg (*args, int);
179  int b, t;
180  char * type_string = 0;
181  char * binding_string = 0;
182 
183  switch ((b = ((bt >> 4) & 0xf)))
184  {
185 #define _(f,n) case n: binding_string = #f; break;
187 #undef _
188  default: break;
189  }
190 
191  switch ((t = ((bt >> 0) & 0xf)))
192  {
193 #define _(f,n) case n: type_string = #f; break;
195 #undef _
196  default: break;
197  }
198 
199  if (binding_string)
200  s = format (s, "%s", binding_string);
201  else
202  s = format (s, "binding 0x%x", b);
203 
204  if (type_string)
205  s = format (s, " %s", type_string);
206  else
207  s = format (s, " type 0x%x", t);
208 
209  return s;
210 }
211 
212 static u8 *
213 format_elf_symbol_visibility (u8 * s, va_list * args)
214 {
215  int visibility = va_arg (*args, int);
216  char * t = 0;
217 
218  switch (visibility)
219  {
220 #define _(f,n) case n: t = #f; break;
222 #undef _
223  }
224 
225  if (t)
226  return format (s, "%s", t);
227  else
228  return format (s, "unknown 0x%x", visibility);
229 }
230 
231 static u8 *
232 format_elf_symbol_section_name (u8 * s, va_list * args)
233 {
234  elf_main_t * em = va_arg (*args, elf_main_t *);
235  int si = va_arg (*args, int);
236  char * t = 0;
237 
238  if (si < vec_len (em->sections))
239  {
240  elf_section_t * es = vec_elt_at_index (em->sections, si);
241  return format (s, "%s", elf_section_name (em, es));
242  }
243 
246  {
247  switch (si)
248  {
249 #define _(f,n) case n: t = #f; break;
251 #undef _
252  default:
253  break;
254  }
255  }
256 
257  if (t)
258  return format (s, "%s", t);
259  else
260  return format (s, "unknown 0x%x", si);
261 }
262 
263 u8 * format_elf_symbol (u8 * s, va_list * args)
264 {
265  elf_main_t * em = va_arg (*args, elf_main_t *);
266  elf_symbol_table_t * t = va_arg (*args, elf_symbol_table_t *);
267  elf64_symbol_t * sym = va_arg (*args, elf64_symbol_t *);
268 
269  if (! sym)
270  return format (s, "%=32s%=16s%=16s%=16s%=16s%=16s",
271  "Symbol", "Size", "Value", "Type", "Visibility", "Section");
272 
273  s = format (s, "%-32s%16Ld%16Lx%=16U%=16U%U",
274  elf_symbol_name (t, sym),
275  sym->size, sym->value,
276  format_elf_symbol_binding_and_type, sym->binding_and_type,
277  format_elf_symbol_visibility, sym->visibility,
278  format_elf_symbol_section_name, em, sym->section_index);
279 
280  return s;
281 }
282 
283 static u8 *
284 format_elf_relocation_type (u8 * s, va_list * args)
285 {
286  elf_main_t * em = va_arg (*args, elf_main_t *);
287  int type = va_arg (*args, int);
288  char * t = 0;
289 
290  switch (em->first_header.architecture)
291  {
292 #define _(f,i) [i] = #f,
293 
294  case ELF_ARCH_X86_64:
295  {
296  static char * tab[] = {
298  };
299 
300 #undef _
301  if (type < ARRAY_LEN (tab))
302  t = tab[type];
303  break;
304  }
305 
306  default:
307  break;
308  }
309 
310  if (! t)
311  s = format (s, "0x%02x", type);
312  else
313  s = format (s, "%s", t);
314 
315  return s;
316 }
317 
318 static u8 *
319 format_elf_relocation (u8 * s, va_list * args)
320 {
321  elf_main_t * em = va_arg (*args, elf_main_t *);
323  elf_symbol_table_t * t;
324  elf64_symbol_t * sym;
325 
326  if (! r)
327  return format (s, "%=16s%=16s%=16s", "Address", "Type", "Symbol");
328 
329  t = vec_elt_at_index (em->symbol_tables, 0);
330  sym = vec_elt_at_index (t->symbols, r->symbol_and_type >> 32);
331 
332  s = format (s, "%16Lx%16U",
333  r->address,
335 
336  if (sym->section_index != 0)
337  {
338  elf_section_t * es;
339  es = vec_elt_at_index (em->sections, sym->section_index);
340  s = format (s, " (section %s)", elf_section_name (em, es));
341  }
342 
343  if (sym->name != 0)
344  s = format (s, " %s", elf_symbol_name (t, sym));
345 
346  {
347  i64 a = r->addend;
348  if (a != 0)
349  s = format (s, " %c 0x%Lx",
350  a > 0 ? '+' : '-',
351  a > 0 ? a : -a);
352  }
353 
354  return s;
355 }
356 
357 static u8 *
358 format_elf_dynamic_entry_type (u8 * s, va_list * args)
359 {
360  u32 type = va_arg (*args, u32);
361  char * t = 0;
362  switch (type)
363  {
364 #define _(f,n) case n: t = #f; break;
366 #undef _
367  default: break;
368  }
369  if (t)
370  return format (s, "%s", t);
371  else
372  return format (s, "unknown 0x%x", type);
373 }
374 
375 static u8 *
376 format_elf_dynamic_entry (u8 * s, va_list * args)
377 {
378  elf_main_t * em = va_arg (*args, elf_main_t *);
379  elf64_dynamic_entry_t * e = va_arg (*args, elf64_dynamic_entry_t *);
380 
381  if (! e)
382  return format (s, "%=40s%=16s", "Type", "Data");
383 
384  s = format (s, "%=40U",
386  switch (e->type)
387  {
388  case ELF_DYNAMIC_ENTRY_NEEDED_LIBRARY:
389  case ELF_DYNAMIC_ENTRY_RPATH:
390  case ELF_DYNAMIC_ENTRY_RUN_PATH:
391  s = format (s, "%s", em->dynamic_string_table + e->data);
392  break;
393 
394  case ELF_DYNAMIC_ENTRY_INIT_FUNCTION:
395  case ELF_DYNAMIC_ENTRY_FINI_FUNCTION:
396  case ELF_DYNAMIC_ENTRY_SYMBOL_HASH:
397  case ELF_DYNAMIC_ENTRY_GNU_HASH:
398  case ELF_DYNAMIC_ENTRY_STRING_TABLE:
399  case ELF_DYNAMIC_ENTRY_SYMBOL_TABLE:
400  case ELF_DYNAMIC_ENTRY_PLT_GOT:
401  case ELF_DYNAMIC_ENTRY_PLT_RELOCATION_ADDRESS:
402  case ELF_DYNAMIC_ENTRY_RELA_ADDRESS:
403  case ELF_DYNAMIC_ENTRY_VERSION_NEED:
404  case ELF_DYNAMIC_ENTRY_VERSYM:
405  {
407  if (es)
408  s = format (s, "section %s", elf_section_name (em, es));
409  else
410  s = format (s, "0x%Lx", e->data);
411  break;
412  }
413 
414  default:
415  s = format (s, "0x%Lx", e->data);
416  break;
417  }
418 
419  return s;
420 }
421 
422 static u8 * format_elf_architecture (u8 * s, va_list * args)
423 {
424  int a = va_arg (*args, int);
425  char * t;
426 
427  switch (a)
428  {
429 #define _(f,n) case n: t = #f; break;
431 #undef _
432  default:
433  return format (s, "unknown 0x%x", a);
434  }
435 
436  return format (s, "%s", t);
437 }
438 
439 static u8 * format_elf_abi (u8 * s, va_list * args)
440 {
441  int a = va_arg (*args, int);
442  char * t;
443 
444  switch (a)
445  {
446 #define _(f,n) case n: t = #f; break;
448 #undef _
449  default:
450  return format (s, "unknown 0x%x", a);
451  }
452 
453  return format (s, "%s", t);
454 }
455 
456 static u8 * format_elf_file_class (u8 * s, va_list * args)
457 {
458  int a = va_arg (*args, int);
459  char * t;
460 
461  switch (a)
462  {
463 #define _(f) case ELF_##f: t = #f; break;
465 #undef _
466  default:
467  return format (s, "unknown 0x%x", a);
468  }
469 
470  return format (s, "%s", t);
471 }
472 
473 static u8 * format_elf_file_type (u8 * s, va_list * args)
474 {
475  int a = va_arg (*args, int);
476  char * t;
477 
478  if (a >= ELF_ARCH_SPECIFIC_LO && a <= ELF_ARCH_SPECIFIC_HI)
479  return format (s, "arch-specific 0x%x", a - ELF_ARCH_SPECIFIC_LO);
480 
481  if (a >= ELF_OS_SPECIFIC_LO && a <= ELF_OS_SPECIFIC_HI)
482  return format (s, "os-specific 0x%x", a - ELF_OS_SPECIFIC_LO);
483 
484  switch (a)
485  {
486 #define _(f,n) case n: t = #f; break;
488 #undef _
489  default:
490  return format (s, "unknown 0x%x", a);
491  }
492 
493  return format (s, "%s", t);
494 }
495 
496 static u8 * format_elf_data_encoding (u8 * s, va_list * args)
497 {
498  int a = va_arg (*args, int);
499  char * t;
500 
501  switch (a)
502  {
503 #define _(f) case ELF_##f: t = #f; break;
505 #undef _
506  default:
507  return format (s, "unknown 0x%x", a);
508  }
509 
510  return format (s, "%s", t);
511 }
512 
513 static int elf_section_offset_compare (void *a1, void *a2)
514 {
515  elf_section_t *s1 = a1;
516  elf_section_t *s2 = a2;
517 
518  return ((i64)s1->header.file_offset - (i64)s2->header.file_offset);
519 }
520 
521 static int elf_segment_va_compare (void *a1, void *a2)
522 {
523  elf_segment_t *s1 = a1;
524  elf_segment_t *s2 = a2;
525 
526  return ((i64)s1->header.virtual_address - (i64)s2->header.virtual_address);
527 }
528 
529 u8 *
530 format_elf_main (u8 * s, va_list * args)
531 {
532  elf_main_t * em = va_arg (*args, elf_main_t *);
533  u32 verbose = va_arg (*args, u32);
534  elf64_file_header_t * fh = &em->file_header;
535 
536  s = format (s, "File header: machine: %U, file type/class %U/%U, data-encoding: %U, abi: %U version %d\n",
542 
543  s = format (s, " entry 0x%Lx, arch-flags 0x%x",
544  em->file_header.entry_point, em->file_header.flags);
545 
546  if (em->interpreter)
547  s = format (s, "\n interpreter: %s", em->interpreter);
548 
549  {
550  elf_section_t * h, * copy;
551 
552  copy = 0;
553  vec_foreach (h, em->sections)
554  if (h->header.type != ~0)
555  vec_add1 (copy, h[0]);
556 
558 
559  s = format (s, "\nSections %d at file offset 0x%Lx-0x%Lx:\n",
560  fh->section_header_count,
561  fh->section_header_file_offset,
562  fh->section_header_file_offset + fh->section_header_count * fh->section_header_size);
563  s = format (s, "%U\n", format_elf_section, em, 0);
564  vec_foreach (h, copy)
565  s = format (s, "%U\n", format_elf_section, em, h);
566 
567  vec_free (copy);
568  }
569 
570  {
571  elf_segment_t * h, * copy;
572 
573  copy = 0;
574  vec_foreach (h, em->segments)
575  if (h->header.type != ELF_SEGMENT_UNUSED && h->header.type != ~0)
576  vec_add1 (copy, h[0]);
577 
578  /* Sort segments by address. */
580 
581  s = format (s, "\nSegments: %d at file offset 0x%Lx-0x%Lx:\n",
582  fh->segment_header_count,
583  fh->segment_header_file_offset,
584  fh->segment_header_file_offset + fh->segment_header_count * fh->segment_header_size);
585 
586  s = format (s, "%U\n", format_elf_segment, 0);
587  vec_foreach (h, copy)
588  s = format (s, "%U\n", format_elf_segment, h);
589 
590  vec_free (copy);
591  }
592 
593  if ((verbose & FORMAT_ELF_MAIN_SYMBOLS)
594  && vec_len (em->symbol_tables) > 0)
595  {
596  elf_symbol_table_t * t;
597  elf64_symbol_t * sym;
598  elf_section_t * es;
599 
600  vec_foreach (t, em->symbol_tables)
601  {
602  es = vec_elt_at_index (em->sections, t->section_index);
603  s = format (s, "\nSymbols for section %s:\n", elf_section_name (em, es));
604 
605  s = format (s, "%U\n", format_elf_symbol, em, 0, 0);
606  vec_foreach (sym, t->symbols)
607  s = format (s, "%U\n", format_elf_symbol, em, t, sym);
608  }
609  }
610 
611  if ((verbose & FORMAT_ELF_MAIN_RELOCATIONS)
612  && vec_len (em->relocation_tables) > 0)
613  {
616  elf_section_t * es;
617 
619  {
620  es = vec_elt_at_index (em->sections, t->section_index);
621  r = t->relocations;
622  s = format (s, "\nRelocations for section %s:\n",
623  elf_section_name (em, es));
624 
625  s = format (s, "%U\n", format_elf_relocation, em, 0);
626  vec_foreach (r, t->relocations)
627  {
628  s = format (s, "%U\n",
629  format_elf_relocation, em, r);
630  }
631  }
632  }
633 
634  if ((verbose & FORMAT_ELF_MAIN_DYNAMIC)
635  && vec_len (em->dynamic_entries) > 0)
636  {
637  elf64_dynamic_entry_t * es, * e;
638  s = format (s, "\nDynamic linker information:\n");
639  es = vec_dup (em->dynamic_entries);
640  s = format (s, "%U\n", format_elf_dynamic_entry, em, 0);
641  vec_foreach (e, es)
642  s = format (s, "%U\n", format_elf_dynamic_entry, em, e);
643  }
644 
645  return s;
646 }
647 
648 static void
649 elf_parse_segments (elf_main_t * em, void * data)
650 {
651  void * d = data + em->file_header.segment_header_file_offset;
652  uword n = em->file_header.segment_header_count;
653  uword i;
654 
655  vec_resize (em->segments, n);
656 
657  for (i = 0; i < n; i++)
658  {
659  em->segments[i].index = i;
660 
661  if (em->first_header.file_class == ELF_64BIT)
662  {
663  elf64_segment_header_t * h = d;
664 #define _(t,f) em->segments[i].header.f = elf_swap_##t (em, h->f);
666 #undef _
667  d = (h + 1);
668  }
669  else
670  {
671  elf32_segment_header_t * h = d;
672 #define _(t,f) em->segments[i].header.f = elf_swap_##t (em, h->f);
674 #undef _
675  d = (h + 1);
676  }
677  }
678 }
679 
680 static void
681 elf_parse_sections (elf_main_t * em, void * data)
682 {
683  elf64_file_header_t * fh = &em->file_header;
684  elf_section_t * s;
685  void * d = data + fh->section_header_file_offset;
686  uword n = fh->section_header_count;
687  uword i;
688 
689  vec_resize (em->sections, n);
690 
691  for (i = 0; i < n; i++)
692  {
693  s = em->sections + i;
694 
695  s->index = i;
696 
697  if (em->first_header.file_class == ELF_64BIT)
698  {
699  elf64_section_header_t * h = d;
700 #define _(t,f) em->sections[i].header.f = elf_swap_##t (em, h->f);
702 #undef _
703  d = (h + 1);
704  }
705  else
706  {
707  elf32_section_header_t * h = d;
708 #define _(t,f) em->sections[i].header.f = elf_swap_##t (em, h->f);
710 #undef _
711  d = (h + 1);
712  }
713 
714  if (s->header.type != ELF_SECTION_NO_BITS)
715  vec_add (s->contents, data + s->header.file_offset, s->header.file_size);
716  }
717 
718  s = vec_elt_at_index (em->sections, fh->section_header_string_table_index);
719 
720  em->section_by_name
721  = hash_create_string (/* # elts */ vec_len (em->sections),
722  /* sizeof of value */ sizeof (uword));
723 
724  vec_foreach (s, em->sections)
725  {
727  elf_section_name (em, s),
728  s - em->sections);
730  s->header.exec_address,
731  s - em->sections);
732  }
733 }
734 
735 static void
737 {
738  elf_symbol_table_t * tab;
739  elf32_symbol_t * sym32;
740  elf64_symbol_t * sym64;
741  uword i;
742 
743  if (s->header.type == ELF_SECTION_DYNAMIC_SYMBOL_TABLE)
745 
746  vec_add2 (em->symbol_tables, tab, 1);
747 
748  tab->section_index = s->index;
749 
750  if (em->first_header.file_class == ELF_64BIT)
751  {
752  tab->symbols = elf_get_section_contents (em, s - em->sections, sizeof (tab->symbols[0]));
753  for (i = 0; i < vec_len (tab->symbols); i++)
754  {
755 #define _(t,f) tab->symbols[i].f = elf_swap_##t (em, tab->symbols[i].f);
757 #undef _
758  }
759  }
760  else
761  {
762  sym32 = elf_get_section_contents (em, s - em->sections, sizeof (sym32[0]));
763  vec_clone (tab->symbols, sym32);
764  for (i = 0; i < vec_len (tab->symbols); i++)
765  {
766 #define _(t,f) tab->symbols[i].f = elf_swap_##t (em, sym32[i].f);
768 #undef _
769  }
770  }
771 
772  if (s->header.link == 0)
773  return;
774 
775  tab->string_table =
776  elf_get_section_contents (em, s->header.link, sizeof (tab->string_table[0]));
777  tab->symbol_by_name
778  = hash_create_string (/* # elts */ vec_len (tab->symbols),
779  /* sizeof of value */ sizeof (uword));
780 
781  vec_foreach (sym64, tab->symbols)
782  {
783  if (sym64->name != 0)
785  tab->string_table + sym64->name,
786  sym64 - tab->symbols);
787  }
788 }
789 
790 static void
792 {
793  uword has_addend = s->header.type == ELF_SECTION_RELOCATION_ADD;
795  uword i;
796 
797  vec_add2 (em->relocation_tables, t, 1);
798  t->section_index = s - em->sections;
799 
800  if (em->first_header.file_class == ELF_64BIT)
801  {
802  elf64_relocation_t * r, * rs;
803 
805  sizeof (rs[0]) + has_addend * sizeof (rs->addend[0]));
806 
807  if (em->need_byte_swap)
808  {
809  r = rs;
810  for (i = 0; i < vec_len (r); i++)
811  {
812  r->address = elf_swap_u64 (em, r->address);
814  if (has_addend)
815  r->addend[0] = elf_swap_u64 (em, r->addend[0]);
816  r = elf_relocation_next (r, s->header.type);
817  }
818  }
819 
820  vec_resize (t->relocations, vec_len (rs));
822  vec_free (rs);
823  }
824  else
825  {
827  elf32_relocation_t * r32, * r32s;
828 
829  r32s = elf_get_section_contents (em, t->section_index,
830  sizeof (r32s[0]) + has_addend * sizeof (r32s->addend[0]));
831  vec_resize (t->relocations, vec_len (r32s));
832 
833  r32 = r32s;
834  vec_foreach (r, t->relocations)
835  {
836  r->address = elf_swap_u32 (em, r32->address);
838  r->addend = has_addend ? elf_swap_u32 (em, r32->addend[0]) : 0;
839  r32 = elf_relocation_next (r32, s->header.type);
840  }
841 
842  vec_free (r32s);
843  }
844 }
845 
847 {
848  elf_section_t * s;
849 
850  /* No need to parse symbols twice. */
851  if (em->parsed_symbols)
852  return;
853  em->parsed_symbols = 1;
854 
855  vec_foreach (s, em->sections)
856  {
857  switch (s->header.type)
858  {
859  case ELF_SECTION_SYMBOL_TABLE:
860  case ELF_SECTION_DYNAMIC_SYMBOL_TABLE:
861  add_symbol_table (em, s);
862  break;
863 
864  case ELF_SECTION_RELOCATION_ADD:
865  case ELF_SECTION_RELOCATION:
866  add_relocation_table (em, s);
867  break;
868 
869  default:
870  break;
871  }
872  }
873 }
874 
876 {
877  uword i;
878 
879  /* Start address for sections may have changed. */
880  {
882 
884  {
885  switch (e->type)
886  {
887  case ELF_DYNAMIC_ENTRY_INIT_FUNCTION:
888  case ELF_DYNAMIC_ENTRY_FINI_FUNCTION:
889  case ELF_DYNAMIC_ENTRY_SYMBOL_HASH:
890  case ELF_DYNAMIC_ENTRY_GNU_HASH:
891  case ELF_DYNAMIC_ENTRY_STRING_TABLE:
892  case ELF_DYNAMIC_ENTRY_SYMBOL_TABLE:
893  case ELF_DYNAMIC_ENTRY_PLT_GOT:
894  case ELF_DYNAMIC_ENTRY_PLT_RELOCATION_ADDRESS:
895  case ELF_DYNAMIC_ENTRY_RELA_ADDRESS:
896  case ELF_DYNAMIC_ENTRY_VERSION_NEED:
897  case ELF_DYNAMIC_ENTRY_VERSYM:
898  {
900  /* If section is not found just leave e->data alone. */
901  if (es)
902  e->data = es->header.exec_address;
903  break;
904  }
905 
906  default:
907  break;
908  }
909  }
910  }
911 
912  if (em->first_header.file_class == ELF_64BIT)
913  {
914  elf64_dynamic_entry_t * e, * es;
915 
916  es = em->dynamic_entries;
917  if (em->need_byte_swap)
918  {
919  es = vec_dup (es);
920  vec_foreach (e, es)
921  {
922  e->type = elf_swap_u64 (em, e->type);
923  e->data = elf_swap_u64 (em, e->data);
924  }
925  }
926 
928  if (es != em->dynamic_entries)
929  vec_free (es);
930  }
931  else
932  {
934 
935  vec_clone (es, em->dynamic_entries);
936  if (em->need_byte_swap)
937  {
938  for (i = 0; i < vec_len (es); i++)
939  {
940  es[i].type = elf_swap_u32 (em, em->dynamic_entries[i].type);
941  es[i].data = elf_swap_u32 (em, em->dynamic_entries[i].data);
942  }
943  }
944 
946  vec_free (es);
947  }
948 }
949 
950 clib_error_t *
952  void * data,
953  uword data_bytes)
954 {
955  elf_first_header_t * h = data;
956  elf64_file_header_t * fh = &em->file_header;
957  clib_error_t * error = 0;
958 
959  {
960  char * save = em->file_name;
961  memset (em, 0, sizeof (em[0]));
962  em->file_name = save;
963  }
964 
965  em->first_header = h[0];
966  em->need_byte_swap =
967  CLIB_ARCH_IS_BIG_ENDIAN != (h->data_encoding == ELF_TWOS_COMPLEMENT_BIG_ENDIAN);
969 
970  if (! (h->magic[0] == 0x7f
971  && h->magic[1] == 'E'
972  && h->magic[2] == 'L'
973  && h->magic[3] == 'F'))
974  return clib_error_return (0, "`%s': bad magic", em->file_name);
975 
976  if (h->file_class == ELF_64BIT)
977  {
978  elf64_file_header_t * h64 = (void *) (h + 1);
979 #define _(t,f) fh->f = elf_swap_##t (em, h64->f);
981 #undef _
982  }
983  else
984  {
985  elf32_file_header_t * h32 = (void *) (h + 1);
986 
987 #define _(t,f) fh->f = elf_swap_##t (em, h32->f);
989 #undef _
990  }
991 
992  elf_parse_segments (em, data);
993  elf_parse_sections (em, data);
994 
995  /* Figure which sections are contained in each segment. */
996  {
997  elf_segment_t * g;
998  elf_section_t * s;
999  vec_foreach (g, em->segments)
1000  {
1001  u64 g_lo, g_hi;
1002  u64 s_lo, s_hi;
1003 
1004  if (g->header.memory_size == 0)
1005  continue;
1006 
1007  g_lo = g->header.virtual_address;
1008  g_hi = g_lo + g->header.memory_size;
1009 
1010  vec_foreach (s, em->sections)
1011  {
1012  s_lo = s->header.exec_address;
1013  s_hi = s_lo + s->header.file_size;
1014 
1015  if (s_lo >= g_lo && s_hi <= g_hi)
1016  {
1017  g->section_index_bitmap = clib_bitmap_ori (g->section_index_bitmap, s->index);
1018  s->segment_index_bitmap = clib_bitmap_ori (s->segment_index_bitmap, g->index);
1019  }
1020  }
1021  }
1022  }
1023 
1024  return error;
1025 }
1026 
1027 #ifdef CLIB_UNIX
1028 
1029 static void
1031 {
1032  uword i;
1033 
1034  /* Can't have more than one dynamic section. */
1035  ASSERT (em->dynamic_section_index == 0);
1036  em->dynamic_section_index = s->index;
1037 
1038  if (em->first_header.file_class == ELF_64BIT)
1039  {
1041 
1042  e = elf_get_section_contents (em, s - em->sections, sizeof (e[0]));
1043  if (em->need_byte_swap)
1044  for (i = 0; i < vec_len (e); i++)
1045  {
1046  e[i].type = elf_swap_u64 (em, e[i].type);
1047  e[i].data = elf_swap_u64 (em, e[i].data);
1048  }
1049 
1050  em->dynamic_entries = e;
1051  }
1052  else
1053  {
1055 
1056  e = elf_get_section_contents (em, s - em->sections, sizeof (e[0]));
1057  vec_clone (em->dynamic_entries, e);
1058  if (em->need_byte_swap)
1059  for (i = 0; i < vec_len (e); i++)
1060  {
1061  em->dynamic_entries[i].type = elf_swap_u32 (em, e[i].type);
1062  em->dynamic_entries[i].data = elf_swap_u32 (em, e[i].data);
1063  }
1064 
1065  vec_free (e);
1066  }
1067 }
1068 
1069 static void byte_swap_verneed (elf_main_t * em,
1071 {
1072  uword * entries_swapped = 0;
1073  uword i, j;
1074 
1075  for (i = 0; i < vec_len (vus); i++)
1076  {
1079 
1080  if (clib_bitmap_get (entries_swapped, i))
1081  continue;
1082 
1083  elf_swap_verneed (&n->need);
1084  entries_swapped = clib_bitmap_set (entries_swapped, i, 1);
1085 
1086  if (n->need.first_aux_offset != 0)
1087  {
1088  ASSERT (n->need.first_aux_offset % sizeof (n[0]) == 0);
1089  j = i + (n->need.first_aux_offset / sizeof (n[0]));
1090  while (1)
1091  {
1092  a = vec_elt_at_index (vus, j);
1093  if (! clib_bitmap_get (entries_swapped, j))
1094  {
1095  entries_swapped = clib_bitmap_set (entries_swapped, j, 1);
1096  elf_swap_verneed_aux (&a->aux);
1097  }
1098  if (a->aux.next_offset == 0)
1099  break;
1100  ASSERT (a->aux.next_offset % sizeof (a->aux) == 0);
1101  j += (a->aux.next_offset / sizeof (a->aux));
1102  }
1103  }
1104  }
1105 
1106  clib_bitmap_free (entries_swapped);
1107 }
1108 
1109 static void
1111 {
1113 
1114  if (em->need_byte_swap)
1115  {
1116  vus = vec_dup (vus);
1117  byte_swap_verneed (em, vus);
1118  }
1119 
1121  if (vus != em->verneed)
1122  vec_free (vus);
1123 }
1124 
1125 static void
1126 set_symbol_table (elf_main_t * em, u32 table_index)
1127 {
1128  elf_symbol_table_t * tab = vec_elt_at_index (em->symbol_tables, table_index);
1129 
1130  if (em->first_header.file_class == ELF_64BIT)
1131  {
1132  elf64_symbol_t * s, * syms;
1133 
1134  syms = vec_dup (tab->symbols);
1135  vec_foreach (s, syms)
1136  {
1137 #define _(t,f) s->f = elf_swap_##t (em, s->f);
1139 #undef _
1140  }
1141 
1143  syms, vec_bytes (syms));
1144  }
1145  else
1146  {
1147  elf32_symbol_t * syms;
1148  uword i;
1149  vec_clone (syms, tab->symbols);
1150  for (i = 0; i < vec_len (tab->symbols); i++)
1151  {
1152 #define _(t,f) syms[i].f = elf_swap_##t (em, tab->symbols[i].f);
1154 #undef _
1155  }
1156 
1158  syms, vec_bytes (syms));
1159  }
1160 }
1161 
1162 static char *
1164 {
1165  elf_segment_t * g;
1166  elf_section_t * s;
1167  uword * p;
1168 
1169  vec_foreach (g, em->segments)
1170  {
1171  if (g->header.type == ELF_SEGMENT_INTERP)
1172  break;
1173  }
1174 
1175  if (g >= vec_end (em->segments))
1176  return 0;
1177 
1178  p = hash_get (em->section_by_start_address, g->header.virtual_address);
1179  if (! p)
1180  return 0;
1181 
1182  s = vec_elt_at_index (em->sections, p[0]);
1183  return (char *) vec_dup (s->contents);
1184 }
1185 
1186 static void *
1188  uword start_address,
1189  uword elt_size,
1190  u32 * section_index_result)
1191 {
1192  elf_section_t * s;
1193  clib_error_t * error;
1194 
1195  error = elf_get_section_by_start_address (em, start_address, &s);
1196  if (error)
1197  {
1198  clib_error_report (error);
1199  return 0;
1200  }
1201 
1202  if (section_index_result)
1203  *section_index_result = s->index;
1204 
1205  return elf_get_section_contents (em, s->index, elt_size);
1206 }
1207 
1208 static void elf_parse_dynamic (elf_main_t * em)
1209 {
1210  elf_section_t * s;
1212 
1213  vec_foreach (s, em->sections)
1214  {
1215  switch (s->header.type)
1216  {
1217  case ELF_SECTION_DYNAMIC:
1218  add_dynamic_entries (em, s);
1219  break;
1220 
1221  default:
1222  break;
1223  }
1224  }
1225 
1227  em->dynamic_string_table = 0;
1228 
1229  vec_foreach (e, em->dynamic_entries)
1230  {
1231  switch (e->type)
1232  {
1233  case ELF_DYNAMIC_ENTRY_STRING_TABLE:
1234  ASSERT (vec_len (em->dynamic_string_table) == 0);
1236  = elf_get_section_contents_with_starting_address (em, e->data, sizeof (u8),
1238  break;
1239 
1240  case ELF_DYNAMIC_ENTRY_SYMBOL_TABLE:
1241  {
1242  elf_section_t * s;
1243  clib_error_t * error;
1244 
1245  error = elf_get_section_by_start_address (em, e->data, &s);
1246  if (error)
1247  {
1248  clib_error_report (error);
1249  return;
1250  }
1251 
1253  }
1254  break;
1255 
1256  case ELF_DYNAMIC_ENTRY_VERSYM:
1257  em->versym
1258  = elf_get_section_contents_with_starting_address (em, e->data, sizeof (em->versym[0]),
1259  &em->versym_section_index);
1260  if (em->need_byte_swap)
1261  {
1262  uword i;
1263  for (i = 0; i < vec_len (em->versym); i++)
1264  em->versym[i] = clib_byte_swap_u16 (em->versym[i]);
1265  }
1266  break;
1267 
1268  case ELF_DYNAMIC_ENTRY_VERSION_NEED:
1269  em->verneed
1270  = elf_get_section_contents_with_starting_address (em, e->data, sizeof (em->verneed[0]),
1271  &em->verneed_section_index);
1272  if (em->need_byte_swap)
1273  byte_swap_verneed (em, em->verneed);
1274  break;
1275 
1276  default:
1277  break;
1278  }
1279  }
1280 }
1281 
1282 #include <sys/types.h>
1283 #include <sys/stat.h>
1284 #include <fcntl.h>
1285 
1286 clib_error_t * elf_read_file (elf_main_t * em, char * file_name)
1287 {
1288  int fd;
1289  struct stat fd_stat;
1290  uword mmap_length = 0;
1291  void * data = 0;
1292  clib_error_t * error = 0;
1293 
1294  elf_main_init (em);
1295 
1296  fd = open (file_name, 0);
1297  if (fd < 0)
1298  {
1299  error = clib_error_return_unix (0, "open `%s'", file_name);
1300  goto done;
1301  }
1302 
1303  if (fstat (fd, &fd_stat) < 0)
1304  {
1305  error = clib_error_return_unix (0, "fstat `%s'", file_name);
1306  goto done;
1307  }
1308  mmap_length = fd_stat.st_size;
1309 
1310  data = mmap (0, mmap_length, PROT_READ, MAP_SHARED, fd, /* offset */ 0);
1311  if (~pointer_to_uword (data) == 0)
1312  {
1313  error = clib_error_return_unix (0, "mmap `%s'", file_name);
1314  goto done;
1315  }
1316 
1317  em->file_name = file_name;
1318 
1319  error = elf_parse (em, data, mmap_length);
1320  if (error)
1321  goto done;
1322 
1323  elf_parse_symbols (em);
1324  elf_parse_dynamic (em);
1325 
1326  em->interpreter = elf_find_interpreter (em, data);
1327 
1328  munmap (data, mmap_length);
1329  close (fd);
1330 
1331  return /* no error */ 0;
1332 
1333  done:
1334  elf_main_free (em);
1335  if (fd >= 0)
1336  close (fd);
1337  if (data)
1338  munmap (data, mmap_length);
1339  return error;
1340 }
1341 
1342 typedef struct {
1344 
1346 
1349 
1351 {
1352  uword * p, i, j, l;
1353 
1354  p = hash_get_mem (b->hash, n);
1355  if (p) return p[0];
1356 
1357  l = strlen ((char *) n);
1358  i = vec_len (b->new_table);
1359  vec_add (b->new_table, n, l + 1);
1360 
1361  for (j = 0; j <= l; j++)
1362  {
1363  if (j > 0)
1364  {
1365  p = hash_get_mem (b->hash, n + j);
1366 
1367  /* Sub-string already in table? */
1368  if (p)
1369  continue;
1370  }
1371 
1372  hash_set_mem (b->hash, n + j, i + j);
1373  }
1374 
1375  return i;
1376 }
1377 
1379 {
1380  u8 * n = b->old_table + index;
1381  return string_table_add_name (b, n);
1382 }
1383 
1384 static void string_table_init (string_table_builder_t * b, u8 * old_table)
1385 {
1386  memset (b, 0, sizeof (b[0]));
1387  b->old_table = old_table;
1388  b->hash = hash_create_string (0, sizeof (uword));
1389 }
1390 
1392 {
1393  hash_free (b->hash);
1394  return b->new_table;
1395 }
1396 
1397 static void layout_sections (elf_main_t * em)
1398 {
1399  elf_section_t * s;
1400  u32 n_sections_with_changed_exec_address = 0;
1401  u32 * deferred_symbol_and_string_sections = 0;
1402  u32 n_deleted_sections = 0;
1403  int rebuild = 0;
1404 
1405  /* Re-build section string table (sections may have been deleted). */
1406  if (rebuild)
1407  {
1408  u8 * st = 0;
1409 
1410  vec_foreach (s, em->sections)
1411  {
1412  u8 * name;
1413  if (s->header.type == ~0)
1414  continue;
1415  name = elf_section_name (em, s);
1416  s->header.name = vec_len (st);
1417  vec_add (st, name, strlen ((char *) name) + 1);
1418  }
1419 
1420  s = vec_elt_at_index (em->sections, em->file_header.section_header_string_table_index);
1421 
1422  vec_free (s->contents);
1423  s->contents = st;
1424  }
1425 
1426  /* Re-build dynamic string table. */
1427  if (rebuild && em->dynamic_string_table_section_index != ~0)
1428  {
1430 
1432 
1433  /* Add all dynamic symbols. */
1434  {
1435  elf_symbol_table_t * symtab;
1436  elf64_symbol_t * sym;
1437 
1439  vec_foreach (sym, symtab->symbols)
1440  {
1441  u8 * name = elf_symbol_name (symtab, sym);
1442  sym->name = string_table_add_name (&b, name);
1443  }
1444 
1446  }
1447 
1448  /* Add all dynamic entries. */
1449  {
1451 
1452  vec_foreach (e, em->dynamic_entries)
1453  {
1454  switch (e->type)
1455  {
1456  case ELF_DYNAMIC_ENTRY_NEEDED_LIBRARY:
1457  case ELF_DYNAMIC_ENTRY_RPATH:
1458  case ELF_DYNAMIC_ENTRY_RUN_PATH:
1459  e->data = string_table_add_name_index (&b, e->data);
1460  break;
1461  }
1462  }
1463  }
1464 
1465  /* Add all version needs. */
1466  if (vec_len (em->verneed) > 0)
1467  {
1469 
1470  n = em->verneed;
1471  while (1)
1472  {
1473  n->need.file_name_offset = string_table_add_name_index (&b, n->need.file_name_offset);
1474 
1475  if (n->need.first_aux_offset != 0)
1476  {
1477  a = n + n->need.first_aux_offset / sizeof (n[0]);
1478  while (1)
1479  {
1480  a->aux.name = string_table_add_name_index (&b, a->aux.name);
1481  if (a->aux.next_offset == 0)
1482  break;
1483  a += a->aux.next_offset / sizeof (a[0]);
1484  }
1485  }
1486 
1487  if (n->need.next_offset == 0)
1488  break;
1489 
1490  n += n->need.next_offset / sizeof (n[0]);
1491  }
1492 
1493  set_dynamic_verneed (em);
1494  }
1495 
1497 
1498  vec_free (s->contents);
1499  s->contents = string_table_done (&b);
1500  }
1501 
1502  /* Figure file offsets and exec addresses for sections. */
1503  {
1504  u64 exec_address = 0, file_offset = 0;
1505  u64 file_size, align_size;
1506 
1507  vec_foreach (s, em->sections)
1508  {
1509  /* Ignore deleted and unused sections. */
1510  switch (s->header.type)
1511  {
1512  case ~0:
1513  n_deleted_sections++;
1514  case ELF_SECTION_UNUSED:
1515  continue;
1516 
1517  case ELF_SECTION_STRING_TABLE:
1518  case ELF_SECTION_SYMBOL_TABLE:
1519  if (! (s->index == em->dynamic_string_table_section_index
1520  || s->index == em->file_header.section_header_string_table_index))
1521  {
1522  vec_add1 (deferred_symbol_and_string_sections, s->index);
1523  continue;
1524  }
1525  break;
1526 
1527  default:
1528  break;
1529  }
1530 
1531  exec_address = round_pow2_u64 (exec_address, s->header.align);
1532 
1533  /* Put sections we added at end of file. */
1534  if (s->header.file_offset == ~0)
1535  s->header.file_offset = file_offset;
1536 
1537  /* Follow gaps in original file. */
1538  if (s->header.exec_address > exec_address)
1539  {
1540  exec_address = s->header.exec_address;
1541  file_offset = s->header.file_offset;
1542  }
1543 
1544  if (s->header.flags & ELF_SECTION_FLAG_ALLOC)
1545  {
1546  s->exec_address_change = exec_address - s->header.exec_address;
1547  n_sections_with_changed_exec_address += s->exec_address_change != 0;
1548  s->header.exec_address = exec_address;
1549  }
1550 
1551  if (s->header.type == ELF_SECTION_NO_BITS)
1552  file_size = s->header.file_size;
1553  else
1554  file_size = vec_len (s->contents);
1555 
1556  {
1557  u64 align;
1558 
1559  if (s + 1 >= vec_end (em->sections))
1560  align = 16;
1561  else if (s[1].header.type == ELF_SECTION_NO_BITS)
1562  align = 8;
1563  else
1564  align = s[1].header.align;
1565 
1566  if (s->header.flags & ELF_SECTION_FLAG_ALLOC)
1567  {
1568  u64 v = round_pow2_u64 (exec_address + file_size, align);
1569  align_size = v - exec_address;
1570  }
1571  else
1572  {
1573  u64 v = round_pow2_u64 (file_offset + file_size, align);
1574  align_size = v - file_offset;
1575  }
1576  }
1577 
1578  s->header.file_offset = file_offset;
1579  s->header.file_size = file_size;
1580  s->align_size = align_size;
1581 
1582  if (s->header.type != ELF_SECTION_NO_BITS)
1583  file_offset += align_size;
1584  exec_address += align_size;
1585  }
1586 
1587  /* Section headers go after last section but before symbol/string
1588  tables. */
1589  {
1590  elf64_file_header_t * fh = &em->file_header;
1591 
1592  fh->section_header_file_offset = file_offset;
1593  fh->section_header_count = vec_len (em->sections) - n_deleted_sections;
1594  file_offset += fh->section_header_count * fh->section_header_size;
1595  }
1596 
1597  {
1598  int i;
1599  for (i = 0; i < vec_len (deferred_symbol_and_string_sections); i++)
1600  {
1601  s = vec_elt_at_index (em->sections, deferred_symbol_and_string_sections[i]);
1602 
1603  s->header.file_offset = file_offset;
1604  s->header.file_size = vec_len (s->contents);
1605 
1606  align_size = round_pow2 (vec_len (s->contents), 16);
1607  s->align_size = align_size;
1608  file_offset += align_size;
1609  }
1610  vec_free (deferred_symbol_and_string_sections);
1611  }
1612  }
1613 
1614  /* Update dynamic entries now that sections have been assigned
1615  possibly new addresses. */
1616  if (rebuild)
1618 
1619  /* Update segments for changed section addresses. */
1620  {
1621  elf_segment_t * g;
1622  uword si;
1623 
1624  vec_foreach (g, em->segments)
1625  {
1626  u64 s_lo, s_hi, f_lo = 0;
1627  u32 n_sections = 0;
1628 
1629  if (g->header.memory_size == 0)
1630  continue;
1631 
1632  s_lo = s_hi = 0;
1634  u64 lo, hi;
1635 
1636  s = vec_elt_at_index (em->sections, si);
1637  lo = s->header.exec_address;
1638  hi = lo + s->align_size;
1639  if (n_sections == 0)
1640  {
1641  s_lo = lo;
1642  s_hi = hi;
1643  f_lo = s->header.file_offset;
1644  n_sections++;
1645  }
1646  else
1647  {
1648  if (lo < s_lo)
1649  {
1650  s_lo = lo;
1651  f_lo = s->header.file_offset;
1652  }
1653  if (hi > s_hi)
1654  s_hi = hi;
1655  }
1656  }));
1657 
1658  if (n_sections == 0)
1659  continue;
1660 
1661  /* File offset zero includes ELF headers/segment headers.
1662  Don't change that. */
1663  if (g->header.file_offset == 0
1664  && g->header.type == ELF_SEGMENT_LOAD)
1665  {
1666  s_lo = g->header.virtual_address;
1667  f_lo = g->header.file_offset;
1668  }
1669 
1670  g->header.virtual_address = s_lo;
1671  g->header.physical_address = s_lo;
1672  g->header.file_offset = f_lo;
1673  g->header.memory_size = s_hi - s_lo;
1674  }
1675  }
1676 }
1677 
1678 clib_error_t * elf_write_file (elf_main_t * em, char * file_name)
1679 {
1680  int fd;
1681  FILE * f;
1682  clib_error_t * error = 0;
1683 
1684  fd = open (file_name, O_CREAT | O_RDWR | O_TRUNC, 0755);
1685  if (fd < 0)
1686  return clib_error_return_unix (0, "open `%s'", file_name);
1687 
1688  f = fdopen (fd, "w");
1689 
1690  /* Section contents may have changed. So, we need to update
1691  stuff to reflect this. */
1692  layout_sections (em);
1693 
1694  /* Write first header. */
1695  {
1697 
1698  elf_swap_first_header (em, &h);
1699  if (fwrite (&h, sizeof (h), 1, f) != 1)
1700  {
1701  error = clib_error_return_unix (0, "write first header");
1702  goto error;
1703  }
1704  }
1705 
1706  /* Write file header. */
1707  {
1709 
1710  /* Segment headers are after first header. */
1711  h.segment_header_file_offset = sizeof (elf_first_header_t);
1712  if (em->first_header.file_class == ELF_64BIT)
1713  h.segment_header_file_offset += sizeof (elf64_file_header_t);
1714  else
1715  h.segment_header_file_offset += sizeof (elf32_file_header_t);
1716 
1717  if (em->first_header.file_class == ELF_64BIT)
1718  {
1719 #define _(t,field) h.field = elf_swap_##t (em, h.field);
1721 #undef _
1722 
1723  if (fwrite (&h, sizeof (h), 1, f) != 1)
1724  {
1725  error = clib_error_return_unix (0, "write file header");
1726  goto error;
1727  }
1728  }
1729  else
1730  {
1731  elf32_file_header_t h32;
1732 
1733 #define _(t,field) h32.field = elf_swap_##t (em, h.field);
1735 #undef _
1736 
1737  if (fwrite (&h32, sizeof (h32), 1, f) != 1)
1738  {
1739  error = clib_error_return_unix (0, "write file header");
1740  goto error;
1741  }
1742  }
1743  }
1744 
1745  /* Write segment headers. */
1746  {
1747  elf_segment_t * s;
1748 
1749  vec_foreach (s, em->segments)
1750  {
1752 
1753  if (s->header.type == ~0)
1754  continue;
1755 
1756  h = s->header;
1757 
1758  if (em->first_header.file_class == ELF_64BIT)
1759  {
1760 #define _(t,field) h.field = elf_swap_##t (em, h.field);
1762 #undef _
1763 
1764  if (fwrite (&h, sizeof (h), 1, f) != 1)
1765  {
1766  error = clib_error_return_unix (0, "write segment header %U", format_elf_segment, em, s);
1767  goto error;
1768  }
1769  }
1770  else
1771  {
1773 
1774 #define _(t,field) h32.field = elf_swap_##t (em, h.field);
1776 #undef _
1777 
1778  if (fwrite (&h32, sizeof (h32), 1, f) != 1)
1779  {
1780  error = clib_error_return_unix (0, "write segment header %U", format_elf_segment, em, s);
1781  goto error;
1782  }
1783  }
1784  }
1785  }
1786 
1787  /* Write contents for all sections. */
1788  {
1789  elf_section_t * s;
1790 
1791  vec_foreach (s, em->sections)
1792  {
1793  if (s->header.file_size == 0)
1794  continue;
1795 
1796  if (fseek (f, s->header.file_offset, SEEK_SET) < 0)
1797  return clib_error_return_unix (0, "fseek 0x%Lx", s->header.file_offset);
1798 
1799  if (s->header.type == ELF_SECTION_NO_BITS)
1800  /* don't write for .bss sections */;
1801  else if (fwrite (s->contents, vec_len (s->contents), 1, f) != 1)
1802  {
1803  error = clib_error_return_unix (0, "write %s section contents", elf_section_name (em, s));
1804  goto error;
1805  }
1806  }
1807 
1808  /* Finally write section headers. */
1809  if (fseek (f, em->file_header.section_header_file_offset, SEEK_SET) < 0)
1810  return clib_error_return_unix (0, "fseek 0x%Lx", em->file_header.section_header_file_offset);
1811 
1812  vec_foreach (s, em->sections)
1813  {
1815 
1816  if (s->header.type == ~0)
1817  continue;
1818 
1819  h = s->header;
1820 
1821  if (em->first_header.file_class == ELF_64BIT)
1822  {
1823 #define _(t,field) h.field = elf_swap_##t (em, h.field);
1825 #undef _
1826 
1827  if (fwrite (&h, sizeof (h), 1, f) != 1)
1828  {
1829  error = clib_error_return_unix (0, "write %s section header", elf_section_name (em, s));
1830  goto error;
1831  }
1832  }
1833  else
1834  {
1836 
1837 #define _(t,field) h32.field = elf_swap_##t (em, h.field);
1839 #undef _
1840 
1841  if (fwrite (&h32, sizeof (h32), 1, f) != 1)
1842  {
1843  error = clib_error_return_unix (0, "write %s section header", elf_section_name (em, s));
1844  goto error;
1845  }
1846  }
1847  }
1848  }
1849 
1850  error:
1851  fclose (f);
1852  return error;
1853 }
1854 
1855 clib_error_t * elf_delete_named_section (elf_main_t * em, char * section_name)
1856 {
1857  elf_section_t * s;
1858  clib_error_t * error;
1859 
1860  error = elf_get_section_by_name (em, section_name, &s);
1861  if (error)
1862  return error;
1863 
1864  s->header.type = ~0;
1865 
1866  return 0;
1867 }
1868 
1869 void
1871  char * section_name,
1872  elf64_section_header_t * header,
1873  void * contents,
1874  uword n_content_bytes)
1875 {
1876  elf_section_t * s, * sts;
1877  u8 * st, * c;
1878  uword * p, is_new_section;
1879 
1880  /* See if section already exists with given name.
1881  If so, just replace contents. */
1882  is_new_section = 0;
1883  if ((p = hash_get_mem (em->section_by_name, section_name)))
1884  {
1885  s = vec_elt_at_index (em->sections, p[0]);
1886  _vec_len (s->contents) = 0;
1887  c = s->contents;
1888  }
1889  else
1890  {
1891  vec_add2 (em->sections, s, 1);
1892  is_new_section = 1;
1893  c = 0;
1894  }
1895 
1896  sts = vec_elt_at_index (em->sections, em->file_header.section_header_string_table_index);
1897  st = sts->contents;
1898 
1899  s->header = header[0];
1900 
1901  s->header.file_offset = ~0;
1902  s->header.file_size = n_content_bytes;
1903  s->index = s - em->sections;
1904 
1905  /* Add name to string table. */
1906  s->header.name = vec_len (st);
1907  vec_add (st, section_name, strlen (section_name));
1908  vec_add1 (st, 0);
1909  sts->contents = st;
1910 
1911  vec_resize (c, n_content_bytes);
1912  clib_memcpy (c, contents, n_content_bytes);
1913  s->contents = c;
1914 
1915  em->file_header.section_header_count += is_new_section && s->header.type != ~0;
1916 }
1917 
1919 {
1920  uword n_deleted = 0;
1921  elf_segment_t * s;
1922 
1923  vec_foreach (s, em->segments)
1924  if (s->header.type == segment_type)
1925  {
1926  s->header.type = ~0;
1927  n_deleted += 1;
1928  }
1929 
1930  ASSERT (em->file_header.segment_header_count >= n_deleted);
1931  em->file_header.segment_header_count -= n_deleted;
1932 
1933  return n_deleted;
1934 }
1935 
1936 #endif /* CLIB_UNIX */
static u8 * format_elf_file_type(u8 *s, va_list *args)
Definition: elf.c:473
always_inline void elf_swap_first_header(elf_main_t *em, elf_first_header_t *h)
Definition: elf.c:23
u8 * format_elf_main(u8 *s, va_list *args)
Definition: elf.c:530
vmrglw vmrglh hi
#define ELF_SYMBOL_SECTION_RESERVED_HI
Definition: elf.h:343
static u8 * format_elf_symbol_section_name(u8 *s, va_list *args)
Definition: elf.c:232
always_inline uword round_pow2(uword x, uword pow2)
Definition: clib.h:255
elf64_segment_header_t header
Definition: elf.h:851
#define vec_clone(NEW_V, OLD_V)
Clone a vector.
Definition: vec.h:358
#define hash_set(h, key, value)
Definition: hash.h:237
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:267
u8 need_byte_swap
Definition: elf.h:862
u32 verneed_section_index
Definition: elf.h:893
a
Definition: bitmap.h:393
static u8 * format_elf_section_type(u8 *s, va_list *args)
Definition: elf.c:77
always_inline void elf_swap_verneed(elf_dynamic_version_need_t *n)
Definition: elf.c:31
static u8 * format_elf_segment_type(u8 *s, va_list *args)
Definition: elf.c:128
#define foreach_elf32_section_header
Definition: elf.h:238
bad routing header type(not 4)") sr_error (NO_MORE_SEGMENTS
#define foreach_elf64_section_header
Definition: elf.h:250
uword elf_delete_segment_with_type(elf_main_t *em, elf_segment_type_t segment_type)
Definition: elf.c:1918
elf_data_encoding_t data_encoding
Definition: elf.h:199
void elf_set_dynamic_entries(elf_main_t *em)
Definition: elf.c:875
u32 index
Definition: elf.h:836
i32 addend[0]
Definition: elf.h:473
static void elf_parse_dynamic(elf_main_t *em)
Definition: elf.c:1208
i64 exec_address_change
Definition: elf.h:845
static u8 * format_elf_relocation(u8 *s, va_list *args)
Definition: elf.c:319
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:480
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:519
#define hash_set_mem(h, key, value)
Definition: hash.h:257
static u8 * format_elf_dynamic_entry(u8 *s, va_list *args)
Definition: elf.c:376
#define clib_error_report(e)
Definition: error.h:126
#define foreach_elf_section_type
Definition: elf.h:350
always_inline void elf_set_section_contents(elf_main_t *em, uword section_index, void *new_contents, uword n_content_bytes)
Definition: elf.h:961
void elf_parse_symbols(elf_main_t *em)
Definition: elf.c:846
#define vec_bytes(v)
Number of data bytes in vector.
u32 dynamic_section_index
Definition: elf.h:889
elf_section_type_t
Definition: elf.h:398
always_inline u8 * elf_section_name(elf_main_t *em, elf_section_t *s)
Definition: elf.h:974
#define FORMAT_ELF_MAIN_RELOCATIONS
Definition: elf.h:997
#define foreach_elf64_file_header
Definition: elf.h:225
#define vec_add(V, E, N)
Add N elements to end of vector V (no header, unspecified alignment)
Definition: vec.h:557
#define foreach_elf_dynamic_version_need_aux_field
Definition: elf.h:702
u8 * contents
Definition: elf.h:847
#define foreach_elf64_symbol_header
Definition: elf.h:293
uword * section_index_bitmap
Definition: elf.h:854
uword * section_by_name
Definition: elf.h:876
#define always_inline
Definition: clib.h:84
always_inline u64 elf_swap_u64(elf_main_t *em, u64 x)
Definition: elf.h:993
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
static void add_symbol_table(elf_main_t *em, elf_section_t *s)
Definition: elf.c:736
unsigned long u64
Definition: types.h:89
#define foreach_elf32_segment_header
Definition: elf.h:263
#define vec_resize(V, N)
Resize a vector (no header, unspecified alignment) Add N elements to end of given vector V...
Definition: vec.h:199
#define vec_end(v)
End (last data address) of vector.
#define foreach_elf_file_class
Definition: elf.h:46
elf_abi_t abi
Definition: elf.h:201
static u8 * format_elf_abi(u8 *s, va_list *args)
Definition: elf.c:439
static void set_symbol_table(elf_main_t *em, u32 table_index)
Definition: elf.c:1126
elf_symbol_table_t * symbol_tables
Definition: elf.h:879
static u8 * format_elf_data_encoding(u8 *s, va_list *args)
Definition: elf.c:496
static uword pointer_to_uword(const void *p)
Definition: types.h:131
#define hash_create_string(elts, value_bytes)
Definition: hash.h:609
#define foreach_elf_dynamic_version_need_field
Definition: elf.h:695
elf_dynamic_version_need_aux_t aux
Definition: elf.h:726
elf_segment_t * segments
Definition: elf.h:872
#define hash_get(h, key)
Definition: hash.h:231
#define clib_bitmap_foreach(i, ai, body)
Definition: bitmap.h:308
clib_error_t * elf_write_file(elf_main_t *em, char *file_name)
Definition: elf.c:1678
#define foreach_elf_symbol_visibility
Definition: elf.h:442
static void add_relocation_table(elf_main_t *em, elf_section_t *s)
Definition: elf.c:791
u64 align_size
Definition: elf.h:843
u32 file_version
Definition: elf.h:209
always_inline void elf_swap_verneed_aux(elf_dynamic_version_need_aux_t *n)
Definition: elf.c:39
u8 * dynamic_string_table
Definition: elf.h:885
#define hash_free(h)
Definition: hash.h:269
#define clib_error_return_unix(e, args...)
Definition: error.h:115
#define vec_dup(V)
Return copy of vector (no header, no alignment)
Definition: vec.h:332
#define foreach_elf_data_encoding
Definition: elf.h:49
#define elf_relocation_next(r, type)
Definition: elf.h:488
static u8 * format_elf_segment(u8 *s, va_list *args)
Definition: elf.c:148
Definition: elf.h:549
#define foreach_elf64_segment_header
Definition: elf.h:273
static void byte_swap_verneed(elf_main_t *em, elf_dynamic_version_need_union_t *vus)
Definition: elf.c:1069
always_inline uword * clib_bitmap_set(uword *ai, uword i, uword value)
Definition: bitmap.h:132
static u32 string_table_add_name_index(string_table_builder_t *b, u32 index)
Definition: elf.c:1378
u8 magic[4]
Definition: elf.h:196
long i64
Definition: types.h:82
always_inline void elf_main_init(elf_main_t *em)
Definition: elf.h:897
#define foreach_elf32_file_header
Definition: elf.h:213
u64 symbol_and_type
Definition: elf.h:478
always_inline uword clib_bitmap_get(uword *ai, uword i)
Definition: bitmap.h:158
always_inline u16 elf_swap_u16(elf_main_t *em, u16 x)
Definition: elf.h:985
static void * elf_get_section_contents_with_starting_address(elf_main_t *em, uword start_address, uword elt_size, u32 *section_index_result)
Definition: elf.c:1187
elf_first_header_t first_header
Definition: elf.h:868
u32 versym_section_index
Definition: elf.h:891
Definition: elf.h:553
always_inline u64 round_pow2_u64(u64 x, u64 pow2)
Definition: clib.h:260
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:298
always_inline void elf_main_free(elf_main_t *em)
Definition: elf.h:903
#define foreach_elf32_symbol_header
Definition: elf.h:284
clib_error_t * elf_read_file(elf_main_t *em, char *file_name)
Definition: elf.c:1286
elf_relocation_with_addend_t * relocations
Definition: elf.h:822
u32 section_index
Definition: elf.h:803
#define clib_memcpy(a, b, c)
Definition: string.h:63
static u8 * format_elf_architecture(u8 *s, va_list *args)
Definition: elf.c:422
static void set_dynamic_verneed(elf_main_t *em)
Definition: elf.c:1110
static void layout_sections(elf_main_t *em)
Definition: elf.c:1397
u32 index
Definition: elf.h:856
elf_architecture_t architecture
Definition: elf.h:207
elf64_symbol_t * symbols
Definition: elf.h:801
static u8 * format_elf_dynamic_entry_type(u8 *s, va_list *args)
Definition: elf.c:358
#define ARRAY_LEN(x)
Definition: clib.h:59
static int elf_segment_va_compare(void *a1, void *a2)
Definition: elf.c:521
#define foreach_elf_x86_64_relocation_type
Definition: elf.h:774
static void elf_parse_segments(elf_main_t *em, void *data)
Definition: elf.c:649
always_inline u8 * elf_symbol_name(elf_symbol_table_t *t, elf64_symbol_t *sym)
Definition: elf.h:818
clib_error_t * elf_delete_named_section(elf_main_t *em, char *section_name)
Definition: elf.c:1855
u32 dynamic_symbol_table_section_index
Definition: elf.h:887
static u8 * format_elf_section(u8 *s, va_list *args)
Definition: elf.c:97
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
char * file_name
Definition: elf.h:866
static void string_table_init(string_table_builder_t *b, u8 *old_table)
Definition: elf.c:1384
u8 * format(u8 *s, char *fmt,...)
Definition: format.c:405
static int elf_section_offset_compare(void *a1, void *a2)
Definition: elf.c:513
elf64_dynamic_entry_t * dynamic_entries
Definition: elf.h:884
i64 addend[0]
Definition: elf.h:479
static u32 string_table_add_name(string_table_builder_t *b, u8 *n)
Definition: elf.c:1350
elf_segment_type_t
Definition: elf.h:521
static void elf_parse_sections(elf_main_t *em, void *data)
Definition: elf.c:681
#define clib_bitmap_free(v)
Definition: bitmap.h:76
u8 parsed_symbols
Definition: elf.h:864
elf_relocation_table_t * relocation_tables
Definition: elf.h:880
elf_section_t * sections
Definition: elf.h:874
u8 * string_table
Definition: elf.h:805
static void add_dynamic_entries(elf_main_t *em, elf_section_t *s)
Definition: elf.c:1030
static u8 * format_elf_relocation_type(u8 *s, va_list *args)
Definition: elf.c:284
elf_dynamic_version_need_t need
Definition: elf.h:725
#define FORMAT_ELF_MAIN_SYMBOLS
Definition: elf.h:996
u64 uword
Definition: types.h:112
#define foreach_elf_symbol_binding
Definition: elf.h:418
#define CLIB_ARCH_IS_BIG_ENDIAN
Definition: byte_order.h:44
u8 * format_elf_symbol(u8 *s, va_list *args)
Definition: elf.c:263
#define FORMAT_ELF_MAIN_DYNAMIC
Definition: elf.h:998
#define ELF_SYMBOL_SECTION_RESERVED_LO
Definition: elf.h:342
#define foreach_elf_symbol_reserved_section_index
Definition: elf.h:337
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
clib_error_t * elf_parse(elf_main_t *em, void *data, uword data_bytes)
Definition: elf.c:951
unsigned char u8
Definition: types.h:56
uword * symbol_by_name
Definition: elf.h:807
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:898
static u8 * format_elf_file_class(u8 *s, va_list *args)
Definition: elf.c:456
uword * segment_index_bitmap
Definition: elf.h:839
elf64_file_header_t file_header
Definition: elf.h:870
always_inline void * elf_get_section_contents(elf_main_t *em, uword section_index, uword elt_size)
Definition: elf.h:936
elf_section_t * elf_get_section_by_start_address_no_check(elf_main_t *em, uword start_address)
Definition: elf.c:60
#define hash_get_mem(h, key)
Definition: hash.h:251
#define foreach_elf_symbol_type
Definition: elf.h:428
u32 dynamic_symbol_table_index
Definition: elf.h:888
char * interpreter
Definition: elf.h:882
elf64_section_header_t header
Definition: elf.h:834
#define vec_foreach(var, vec)
Vector iterator.
elf_dynamic_version_need_union_t * verneed
Definition: elf.h:892
u16 * versym
Definition: elf.h:890
static u8 * format_elf_symbol_visibility(u8 *s, va_list *args)
Definition: elf.c:213
void elf_create_section_with_contents(elf_main_t *em, char *section_name, elf64_section_header_t *header, void *contents, uword n_content_bytes)
Definition: elf.c:1870
#define clib_error_return(e, args...)
Definition: error.h:112
always_inline u16 clib_byte_swap_u16(u16 x)
Definition: byte_order.h:57
clib_error_t * elf_get_section_by_name(elf_main_t *em, char *section_name, elf_section_t **result)
Definition: elf.c:47
static u8 * string_table_done(string_table_builder_t *b)
Definition: elf.c:1391
elf_file_type_t file_type
Definition: elf.h:206
static u8 * format_elf_symbol_binding_and_type(u8 *s, va_list *args)
Definition: elf.c:176
clib_error_t * elf_get_section_by_start_address(elf_main_t *em, uword start_address, elf_section_t **result)
Definition: elf.c:67
elf_file_class_t file_class
Definition: elf.h:198
CLIB vectors are ubiquitous dynamically resized arrays with by user defined "headers".
static char * elf_find_interpreter(elf_main_t *em, void *data)
Definition: elf.c:1163
uword * section_by_start_address
Definition: elf.h:877
always_inline u32 elf_swap_u32(elf_main_t *em, u32 x)
Definition: elf.h:989
u32 dynamic_string_table_section_index
Definition: elf.h:886