aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/recordmcount.c
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/recordmcount.c')
-rw-r--r--scripts/recordmcount.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c
index 26e1271259ba..f2f32eee2c5b 100644
--- a/scripts/recordmcount.c
+++ b/scripts/recordmcount.c
@@ -217,6 +217,39 @@ is_mcounted_section_name(char const *const txtname)
217#define RECORD_MCOUNT_64 217#define RECORD_MCOUNT_64
218#include "recordmcount.h" 218#include "recordmcount.h"
219 219
220/* 64-bit EM_MIPS has weird ELF64_Rela.r_info.
221 * http://techpubs.sgi.com/library/manuals/4000/007-4658-001/pdf/007-4658-001.pdf
222 * We interpret Table 29 Relocation Operation (Elf64_Rel, Elf64_Rela) [p.40]
223 * to imply the order of the members; the spec does not say so.
224 * typedef unsigned char Elf64_Byte;
225 * fails on MIPS64 because their <elf.h> already has it!
226 */
227
228typedef uint8_t myElf64_Byte; /* Type for a 8-bit quantity. */
229
230union mips_r_info {
231 Elf64_Xword r_info;
232 struct {
233 Elf64_Word r_sym; /* Symbol index. */
234 myElf64_Byte r_ssym; /* Special symbol. */
235 myElf64_Byte r_type3; /* Third relocation. */
236 myElf64_Byte r_type2; /* Second relocation. */
237 myElf64_Byte r_type; /* First relocation. */
238 } r_mips;
239};
240
241static uint64_t MIPS64_r_sym(Elf64_Rel const *rp)
242{
243 return w(((union mips_r_info){ .r_info = rp->r_info }).r_mips.r_sym);
244}
245
246static void MIPS64_r_info(Elf64_Rel *const rp, unsigned sym, unsigned type)
247{
248 rp->r_info = ((union mips_r_info){
249 .r_mips = { .r_sym = w(sym), .r_type = type }
250 }).r_info;
251}
252
220static void 253static void
221do_file(char const *const fname) 254do_file(char const *const fname)
222{ 255{
@@ -268,6 +301,7 @@ do_file(char const *const fname)
268 case EM_386: reltype = R_386_32; break; 301 case EM_386: reltype = R_386_32; break;
269 case EM_ARM: reltype = R_ARM_ABS32; break; 302 case EM_ARM: reltype = R_ARM_ABS32; break;
270 case EM_IA_64: reltype = R_IA64_IMM64; gpfx = '_'; break; 303 case EM_IA_64: reltype = R_IA64_IMM64; gpfx = '_'; break;
304 case EM_MIPS: /* reltype: e_class */ gpfx = '_'; break;
271 case EM_PPC: reltype = R_PPC_ADDR32; gpfx = '_'; break; 305 case EM_PPC: reltype = R_PPC_ADDR32; gpfx = '_'; break;
272 case EM_PPC64: reltype = R_PPC64_ADDR64; gpfx = '_'; break; 306 case EM_PPC64: reltype = R_PPC64_ADDR64; gpfx = '_'; break;
273 case EM_S390: /* reltype: e_class */ gpfx = '_'; break; 307 case EM_S390: /* reltype: e_class */ gpfx = '_'; break;
@@ -291,6 +325,10 @@ do_file(char const *const fname)
291 } 325 }
292 if (EM_S390 == w2(ehdr->e_machine)) 326 if (EM_S390 == w2(ehdr->e_machine))
293 reltype = R_390_32; 327 reltype = R_390_32;
328 if (EM_MIPS == w2(ehdr->e_machine)) {
329 reltype = R_MIPS_32;
330 is_fake_mcount32 = MIPS32_is_fake_mcount;
331 }
294 do32(ehdr, fname, reltype); 332 do32(ehdr, fname, reltype);
295 } break; 333 } break;
296 case ELFCLASS64: { 334 case ELFCLASS64: {
@@ -303,6 +341,12 @@ do_file(char const *const fname)
303 } 341 }
304 if (EM_S390 == w2(ghdr->e_machine)) 342 if (EM_S390 == w2(ghdr->e_machine))
305 reltype = R_390_64; 343 reltype = R_390_64;
344 if (EM_MIPS == w2(ghdr->e_machine)) {
345 reltype = R_MIPS_64;
346 Elf64_r_sym = MIPS64_r_sym;
347 Elf64_r_info = MIPS64_r_info;
348 is_fake_mcount64 = MIPS64_is_fake_mcount;
349 }
306 do64(ghdr, fname, reltype); 350 do64(ghdr, fname, reltype);
307 } break; 351 } break;
308 } /* end switch */ 352 } /* end switch */