diff options
Diffstat (limited to 'recipes-devtools/odcctools/files/cctools-287.patch')
-rw-r--r-- | recipes-devtools/odcctools/files/cctools-287.patch | 13095 |
1 files changed, 13095 insertions, 0 deletions
diff --git a/recipes-devtools/odcctools/files/cctools-287.patch b/recipes-devtools/odcctools/files/cctools-287.patch new file mode 100644 index 0000000..6e6dd60 --- /dev/null +++ b/recipes-devtools/odcctools/files/cctools-287.patch @@ -0,0 +1,13095 @@ +Index: odcctools-9.2-ld/libmacho/arch.c +=================================================================== +--- odcctools-9.2-ld.orig/libmacho/arch.c 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/libmacho/arch.c 2013-09-03 21:08:01.865209516 +0000 +@@ -73,6 +73,8 @@ + "PowerPC 64-bit"}, + {"sparc", CPU_TYPE_SPARC, CPU_SUBTYPE_SPARC_ALL, NX_BigEndian, + "SPARC"}, ++ {"arm", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_ALL, NX_LittleEndian, ++ "ARM"}, + {"any", CPU_TYPE_ANY, CPU_SUBTYPE_MULTIPLE, NX_UnknownByteOrder, + "Architecture Independent"}, + {"veo", CPU_TYPE_VEO, CPU_SUBTYPE_VEO_ALL, NX_BigEndian, +@@ -124,6 +126,22 @@ + "PowerPC 970" }, + {"ppc970-64", CPU_TYPE_POWERPC64, CPU_SUBTYPE_POWERPC_970, NX_BigEndian, + "PowerPC 970 64-bit"}, ++ {"armv4t", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V4T, NX_LittleEndian, ++ "arm v4t"}, ++ {"armv5", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V5TEJ, NX_LittleEndian, ++ "arm v5"}, ++ {"xscale", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_XSCALE, NX_LittleEndian, ++ "arm xscale"}, ++ {"armv6", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V6, NX_LittleEndian, ++ "arm v6"}, ++ {"armv7", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7, NX_LittleEndian, ++ "arm v7"}, ++ {"armv7f", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7F, NX_LittleEndian, ++ "arm v7f"}, ++ {"armv7s", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7S, NX_LittleEndian, ++ "arm v7s"}, ++ {"armv7k", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7K, NX_LittleEndian, ++ "arm v7k"}, + {"little", CPU_TYPE_ANY, CPU_SUBTYPE_LITTLE_ENDIAN, NX_LittleEndian, + "Little Endian"}, + {"big", CPU_TYPE_ANY, CPU_SUBTYPE_BIG_ENDIAN, NX_BigEndian, +@@ -218,7 +236,8 @@ + for(ai = ArchInfoTable; ai->name != NULL; ai++) + if(ai->cputype == cputype && + (cpusubtype == CPU_SUBTYPE_MULTIPLE || +- (ai->cpusubtype == cpusubtype))) ++ ((ai->cpusubtype & ~CPU_SUBTYPE_MASK) == ++ (cpusubtype & ~CPU_SUBTYPE_MASK)))) + return(ai); + + if(cputype == CPU_TYPE_I386){ +@@ -234,8 +253,8 @@ + if(q->description == NULL) + return(NULL); + sprintf((char *)q->description, "Intel family %u model %u", +- CPU_SUBTYPE_INTEL_FAMILY(cpusubtype), +- CPU_SUBTYPE_INTEL_MODEL(cpusubtype)); ++ CPU_SUBTYPE_INTEL_FAMILY(cpusubtype & ~CPU_SUBTYPE_MASK), ++ CPU_SUBTYPE_INTEL_MODEL(cpusubtype & ~CPU_SUBTYPE_MASK)); + return((const NXArchInfo *)q); + } + else if(cputype == CPU_TYPE_POWERPC){ +@@ -274,15 +293,16 @@ + struct fat_arch *fat_archs, + uint32_t nfat_archs) + { +- unsigned long i; +- long lowest_family, lowest_model, lowest_index; ++ uint32_t i; ++ int32_t lowest_family, lowest_model, lowest_index; + + /* + * Look for the first exact match. + */ + for(i = 0; i < nfat_archs; i++){ + if(fat_archs[i].cputype == cputype && +- fat_archs[i].cpusubtype == cpusubtype) ++ (fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == ++ (cpusubtype & ~CPU_SUBTYPE_MASK)) + return(fat_archs + i); + } + +@@ -292,7 +312,7 @@ + */ + switch(cputype){ + case CPU_TYPE_I386: +- switch(cpusubtype){ ++ switch(cpusubtype & ~CPU_SUBTYPE_MASK){ + default: + /* + * Intel cpusubtypes after the pentium (same as 586) are handled +@@ -303,7 +323,8 @@ + for(i = 0; i < nfat_archs; i++){ + if(fat_archs[i].cputype != cputype) + continue; +- if(fat_archs[i].cpusubtype == CPU_SUBTYPE_PENT) ++ if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == ++ CPU_SUBTYPE_PENT) + return(fat_archs + i); + } + case CPU_SUBTYPE_PENT: +@@ -315,7 +336,8 @@ + for(i = 0; i < nfat_archs; i++){ + if(fat_archs[i].cputype != cputype) + continue; +- if(fat_archs[i].cpusubtype == CPU_SUBTYPE_486) ++ if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == ++ CPU_SUBTYPE_486) + return(fat_archs + i); + } + break; +@@ -327,7 +349,8 @@ + for(i = 0; i < nfat_archs; i++){ + if(fat_archs[i].cputype != cputype) + continue; +- if(fat_archs[i].cpusubtype == CPU_SUBTYPE_I386_ALL) ++ if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == ++ CPU_SUBTYPE_I386_ALL) + return(fat_archs + i); + } + +@@ -337,19 +360,22 @@ + for(i = 0; i < nfat_archs; i++){ + if(fat_archs[i].cputype != cputype) + continue; +- if(fat_archs[i].cpusubtype == CPU_SUBTYPE_486) ++ if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == ++ CPU_SUBTYPE_486) + return(fat_archs + i); + } + for(i = 0; i < nfat_archs; i++){ + if(fat_archs[i].cputype != cputype) + continue; +- if(fat_archs[i].cpusubtype == CPU_SUBTYPE_486SX) ++ if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == ++ CPU_SUBTYPE_486SX) + return(fat_archs + i); + } + for(i = 0; i < nfat_archs; i++){ + if(fat_archs[i].cputype != cputype) + continue; +- if(fat_archs[i].cpusubtype == CPU_SUBTYPE_586) ++ if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == ++ CPU_SUBTYPE_586) + return(fat_archs + i); + } + /* +@@ -359,25 +385,26 @@ + for(i = 0; i < nfat_archs; i++){ + if(fat_archs[i].cputype != cputype) + continue; +- if(CPU_SUBTYPE_INTEL_FAMILY(fat_archs[i].cpusubtype) < +- lowest_family) ++ if(CPU_SUBTYPE_INTEL_FAMILY(fat_archs[i].cpusubtype & ++ ~CPU_SUBTYPE_MASK) < lowest_family) + lowest_family = CPU_SUBTYPE_INTEL_FAMILY( +- fat_archs[i].cpusubtype); ++ fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK); + } + /* if no intel cputypes found return NULL */ + if(lowest_family == CPU_SUBTYPE_INTEL_FAMILY_MAX + 1) + return(NULL); +- lowest_model = LONG_MAX; ++ lowest_model = INT_MAX; + lowest_index = -1; + for(i = 0; i < nfat_archs; i++){ + if(fat_archs[i].cputype != cputype) + continue; +- if(CPU_SUBTYPE_INTEL_FAMILY(fat_archs[i].cpusubtype) == +- lowest_family){ +- if(CPU_SUBTYPE_INTEL_MODEL(fat_archs[i].cpusubtype) < +- lowest_model){ ++ if(CPU_SUBTYPE_INTEL_FAMILY(fat_archs[i].cpusubtype & ++ ~CPU_SUBTYPE_MASK) == lowest_family){ ++ if(CPU_SUBTYPE_INTEL_MODEL(fat_archs[i].cpusubtype & ++ ~CPU_SUBTYPE_MASK) < lowest_model){ + lowest_model = CPU_SUBTYPE_INTEL_MODEL( +- fat_archs[i].cpusubtype); ++ fat_archs[i].cpusubtype & ++ ~CPU_SUBTYPE_MASK); + lowest_index = i; + } + } +@@ -387,7 +414,8 @@ + for(i = 0; i < nfat_archs; i++){ + if(fat_archs[i].cputype != cputype) + continue; +- if(fat_archs[i].cpusubtype == CPU_SUBTYPE_X86_64_ALL) ++ if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == ++ CPU_SUBTYPE_X86_64_ALL) + return(fat_archs + i); + } + break; +@@ -395,24 +423,27 @@ + for(i = 0; i < nfat_archs; i++){ + if(fat_archs[i].cputype != cputype) + continue; +- if(fat_archs[i].cpusubtype == CPU_SUBTYPE_MC680x0_ALL) ++ if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == ++ CPU_SUBTYPE_MC680x0_ALL) + return(fat_archs + i); + } + /* + * Try to promote if starting from CPU_SUBTYPE_MC680x0_ALL and + * favor the CPU_SUBTYPE_MC68040 over the CPU_SUBTYPE_MC68030_ONLY. + */ +- if(cpusubtype == CPU_SUBTYPE_MC680x0_ALL){ ++ if((cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC680x0_ALL){ + for(i = 0; i < nfat_archs; i++){ + if(fat_archs[i].cputype != cputype) + continue; +- if(fat_archs[i].cpusubtype == CPU_SUBTYPE_MC68040) ++ if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == ++ CPU_SUBTYPE_MC68040) + return(fat_archs + i); + } + for(i = 0; i < nfat_archs; i++){ + if(fat_archs[i].cputype != cputype) + continue; +- if(fat_archs[i].cpusubtype == CPU_SUBTYPE_MC68030_ONLY) ++ if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == ++ CPU_SUBTYPE_MC68030_ONLY) + return(fat_archs + i); + } + } +@@ -428,7 +459,7 @@ + * an exact match. For an unknown subtype pick only the ALL type if + * it exists. + */ +- switch(cpusubtype){ ++ switch(cpusubtype & ~CPU_SUBTYPE_MASK){ + case CPU_SUBTYPE_POWERPC_ALL: + /* + * The CPU_SUBTYPE_POWERPC_ALL is only used by the development +@@ -440,7 +471,8 @@ + for(i = 0; i < nfat_archs; i++){ + if(fat_archs[i].cputype != cputype) + continue; +- if(fat_archs[i].cpusubtype == CPU_SUBTYPE_POWERPC_970) ++ if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == ++ CPU_SUBTYPE_POWERPC_970) + return(fat_archs + i); + } + case CPU_SUBTYPE_POWERPC_7450: +@@ -448,13 +480,15 @@ + for(i = 0; i < nfat_archs; i++){ + if(fat_archs[i].cputype != cputype) + continue; +- if(fat_archs[i].cpusubtype == CPU_SUBTYPE_POWERPC_7450) ++ if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == ++ CPU_SUBTYPE_POWERPC_7450) + return(fat_archs + i); + } + for(i = 0; i < nfat_archs; i++){ + if(fat_archs[i].cputype != cputype) + continue; +- if(fat_archs[i].cpusubtype == CPU_SUBTYPE_POWERPC_7400) ++ if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == ++ CPU_SUBTYPE_POWERPC_7400) + return(fat_archs + i); + } + case CPU_SUBTYPE_POWERPC_750: +@@ -466,44 +500,51 @@ + for(i = 0; i < nfat_archs; i++){ + if(fat_archs[i].cputype != cputype) + continue; +- if(fat_archs[i].cpusubtype == CPU_SUBTYPE_POWERPC_750) ++ if((fat_archs[i].cpusubtype & CPU_SUBTYPE_MASK) == ++ CPU_SUBTYPE_POWERPC_750) + return(fat_archs + i); + } + for(i = 0; i < nfat_archs; i++){ + if(fat_archs[i].cputype != cputype) + continue; +- if(fat_archs[i].cpusubtype == CPU_SUBTYPE_POWERPC_604e) ++ if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == ++ CPU_SUBTYPE_POWERPC_604e) + return(fat_archs + i); + } + for(i = 0; i < nfat_archs; i++){ + if(fat_archs[i].cputype != cputype) + continue; +- if(fat_archs[i].cpusubtype == CPU_SUBTYPE_POWERPC_604) ++ if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == ++ CPU_SUBTYPE_POWERPC_604) + return(fat_archs + i); + } + for(i = 0; i < nfat_archs; i++){ +- if(fat_archs[i].cputype != cputype) ++ if((fat_archs[i].cputype & ~CPU_SUBTYPE_MASK) != cputype) + continue; +- if(fat_archs[i].cpusubtype == CPU_SUBTYPE_POWERPC_603ev) ++ if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == ++ CPU_SUBTYPE_POWERPC_603ev) + return(fat_archs + i); + } + for(i = 0; i < nfat_archs; i++){ + if(fat_archs[i].cputype != cputype) + continue; +- if(fat_archs[i].cpusubtype == CPU_SUBTYPE_POWERPC_603e) ++ if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == ++ CPU_SUBTYPE_POWERPC_603e) + return(fat_archs + i); + } + for(i = 0; i < nfat_archs; i++){ + if(fat_archs[i].cputype != cputype) + continue; +- if(fat_archs[i].cpusubtype == CPU_SUBTYPE_POWERPC_603) ++ if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == ++ CPU_SUBTYPE_POWERPC_603) + return(fat_archs + i); + } + default: + for(i = 0; i < nfat_archs; i++){ + if(fat_archs[i].cputype != cputype) + continue; +- if(fat_archs[i].cpusubtype == CPU_SUBTYPE_POWERPC_ALL) ++ if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == ++ CPU_SUBTYPE_POWERPC_ALL) + return(fat_archs + i); + } + } +@@ -517,7 +558,7 @@ + * 970 (currently only the one 64-bit subtype) + * For an unknown subtype pick only the ALL type if it exists. + */ +- switch(cpusubtype){ ++ switch(cpusubtype & ~CPU_SUBTYPE_MASK){ + case CPU_SUBTYPE_POWERPC_ALL: + /* + * The CPU_SUBTYPE_POWERPC_ALL is only used by the development +@@ -529,14 +570,16 @@ + for(i = 0; i < nfat_archs; i++){ + if(fat_archs[i].cputype != cputype) + continue; +- if(fat_archs[i].cpusubtype == CPU_SUBTYPE_POWERPC_970) ++ if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == ++ CPU_SUBTYPE_POWERPC_970) + return(fat_archs + i); + } + default: + for(i = 0; i < nfat_archs; i++){ + if(fat_archs[i].cputype != cputype) + continue; +- if(fat_archs[i].cpusubtype == CPU_SUBTYPE_POWERPC_ALL) ++ if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == ++ CPU_SUBTYPE_POWERPC_ALL) + return(fat_archs + i); + } + } +@@ -545,7 +588,8 @@ + for(i = 0; i < nfat_archs; i++){ + if(fat_archs[i].cputype != cputype) + continue; +- if(fat_archs[i].cpusubtype == CPU_SUBTYPE_MC88000_ALL) ++ if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == ++ CPU_SUBTYPE_MC88000_ALL) + return(fat_archs + i); + } + break; +@@ -553,7 +597,8 @@ + for(i = 0; i < nfat_archs; i++){ + if(fat_archs[i].cputype != cputype) + continue; +- if(fat_archs[i].cpusubtype == CPU_SUBTYPE_I860_ALL) ++ if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == ++ CPU_SUBTYPE_I860_ALL) + return(fat_archs + i); + } + break; +@@ -561,7 +606,8 @@ + for(i = 0; i < nfat_archs; i++){ + if(fat_archs[i].cputype != cputype) + continue; +- if(fat_archs[i].cpusubtype == CPU_SUBTYPE_HPPA_ALL) ++ if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == ++ CPU_SUBTYPE_HPPA_ALL) + return(fat_archs + i); + } + break; +@@ -569,10 +615,38 @@ + for(i = 0; i < nfat_archs; i++){ + if(fat_archs[i].cputype != cputype) + continue; +- if(fat_archs[i].cpusubtype == CPU_SUBTYPE_SPARC_ALL) ++ if((fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == ++ CPU_SUBTYPE_SPARC_ALL) + return(fat_archs + i); + } + break; ++ case CPU_TYPE_ARM: ++ { ++ /* ++ * ARM is straightforward, since each architecture is backward ++ * compatible with previous architectures. So, we just take the ++ * highest that is less than our target. ++ */ ++ int fat_match_found = 0; ++ uint32_t best_fat_arch = 0; ++ for(i = 0; i < nfat_archs; i++){ ++ if(fat_archs[i].cputype != cputype) ++ continue; ++ if(fat_archs[i].cpusubtype > cpusubtype) ++ continue; ++ if(!fat_match_found){ ++ fat_match_found = 1; ++ best_fat_arch = i; ++ continue; ++ } ++ if(fat_archs[i].cpusubtype > ++ fat_archs[best_fat_arch].cpusubtype) ++ best_fat_arch = i; ++ } ++ if(fat_match_found) ++ return fat_archs + best_fat_arch; ++ } ++ break; + default: + return(NULL); + } +@@ -603,33 +677,34 @@ + if(cputype == CPU_TYPE_X86_64) + return(CPU_SUBTYPE_X86_64_ALL); + +- if(cpusubtype1 == cpusubtype2) ++ if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == ++ (cpusubtype2 & ~CPU_SUBTYPE_MASK)) + return(cpusubtype1); + + switch(cputype){ + case CPU_TYPE_MC680x0: +- if(cpusubtype1 != CPU_SUBTYPE_MC680x0_ALL && +- cpusubtype1 != CPU_SUBTYPE_MC68030_ONLY && +- cpusubtype1 != CPU_SUBTYPE_MC68040) ++ if((cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC680x0_ALL && ++ (cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC68030_ONLY && ++ (cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC68040) + return((cpu_subtype_t)-1); +- if(cpusubtype2 != CPU_SUBTYPE_MC680x0_ALL && +- cpusubtype2 != CPU_SUBTYPE_MC68030_ONLY && +- cpusubtype2 != CPU_SUBTYPE_MC68040) ++ if((cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC680x0_ALL && ++ (cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC68030_ONLY && ++ (cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC68040) + return((cpu_subtype_t)-1); + +- if(cpusubtype1 == CPU_SUBTYPE_MC68030_ONLY && +- cpusubtype2 == CPU_SUBTYPE_MC68040) ++ if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68030_ONLY && ++ (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68040) + return((cpu_subtype_t)-1); +- if(cpusubtype1 == CPU_SUBTYPE_MC68040 && +- cpusubtype2 == CPU_SUBTYPE_MC68030_ONLY) ++ if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68040 && ++ (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68030_ONLY) + return((cpu_subtype_t)-1); + +- if(cpusubtype1 == CPU_SUBTYPE_MC68030_ONLY || +- cpusubtype2 == CPU_SUBTYPE_MC68030_ONLY) ++ if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68030_ONLY || ++ (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68030_ONLY) + return(CPU_SUBTYPE_MC68030_ONLY); + +- if(cpusubtype1 == CPU_SUBTYPE_MC68040 || +- cpusubtype2 == CPU_SUBTYPE_MC68040) ++ if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68040 || ++ (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC68040) + return(CPU_SUBTYPE_MC68040); + break; /* logically can't get here */ + +@@ -639,66 +714,124 @@ + * anything with the 601 becomes 601. All other non exact matches + * combine to the higher value subtype. + */ +- if(cpusubtype1 == CPU_SUBTYPE_POWERPC_ALL) ++ if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_ALL) + return(cpusubtype2); +- if(cpusubtype2 == CPU_SUBTYPE_POWERPC_ALL) ++ if((cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_ALL) + return(cpusubtype1); + +- if(cpusubtype1 == CPU_SUBTYPE_POWERPC_601 || +- cpusubtype2 == CPU_SUBTYPE_POWERPC_601) ++ if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_601 || ++ (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_601) + return(CPU_SUBTYPE_POWERPC_601); + +- if(cpusubtype1 > cpusubtype2) ++ if((cpusubtype1 & ~CPU_SUBTYPE_MASK) > ++ (cpusubtype2 & ~CPU_SUBTYPE_MASK)) + return(cpusubtype1); + else + return(cpusubtype2); + break; /* logically can't get here */ + + case CPU_TYPE_MC88000: +- if(cpusubtype1 != CPU_SUBTYPE_MC88000_ALL && +- cpusubtype1 != CPU_SUBTYPE_MC88110) ++ if((cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC88000_ALL && ++ (cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC88110) + return((cpu_subtype_t)-1); +- if(cpusubtype2 != CPU_SUBTYPE_MC88000_ALL && +- cpusubtype2 != CPU_SUBTYPE_MC88110) ++ if((cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC88000_ALL && ++ (cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_MC88110) + return((cpu_subtype_t)-1); + +- if(cpusubtype1 == CPU_SUBTYPE_MC88110 || +- cpusubtype2 == CPU_SUBTYPE_MC88110) ++ if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC88110 || ++ (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_MC88110) + return(CPU_SUBTYPE_MC88110); + + break; /* logically can't get here */ + + case CPU_TYPE_I860: +- if(cpusubtype1 != CPU_SUBTYPE_I860_ALL && +- cpusubtype1 != CPU_SUBTYPE_I860_860) ++ if((cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_I860_ALL && ++ (cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_I860_860) + return((cpu_subtype_t)-1); +- if(cpusubtype2 != CPU_SUBTYPE_I860_ALL && +- cpusubtype2 != CPU_SUBTYPE_I860_860) ++ if((cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_I860_ALL && ++ (cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_I860_860) + return((cpu_subtype_t)-1); + +- if(cpusubtype1 == CPU_SUBTYPE_I860_860 || +- cpusubtype2 == CPU_SUBTYPE_I860_860) ++ if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_I860_860 || ++ (cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_I860_860) + return(CPU_SUBTYPE_I860_860); + break; /* logically can't get here */ + + case CPU_TYPE_HPPA: +- if(cpusubtype1 != CPU_SUBTYPE_HPPA_ALL && +- cpusubtype1 != CPU_SUBTYPE_HPPA_7100LC) ++ if((cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_HPPA_ALL && ++ (cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_HPPA_7100LC) + return((cpu_subtype_t)-1); +- if(cpusubtype2 != CPU_SUBTYPE_HPPA_ALL && +- cpusubtype2 != CPU_SUBTYPE_HPPA_7100LC) ++ if((cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_HPPA_ALL && ++ (cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_HPPA_7100LC) + return((cpu_subtype_t)-1); + + return(CPU_SUBTYPE_HPPA_7100LC); + break; /* logically can't get here */ + + case CPU_TYPE_SPARC: +- if(cpusubtype1 != CPU_SUBTYPE_SPARC_ALL) ++ if((cpusubtype1 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_SPARC_ALL) + return((cpu_subtype_t)-1); +- if(cpusubtype2 != CPU_SUBTYPE_SPARC_ALL) ++ if((cpusubtype2 & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_SPARC_ALL) + return((cpu_subtype_t)-1); + break; /* logically can't get here */ + ++ case CPU_TYPE_ARM: ++ /* ++ * Combinability matrix for ARM: ++ * V4T V5 XSCALE V6 V7 ALL ++ * ~~~ ~~ ~~~~~~ ~~ ~~ ~~~ ++ * V4T V4T V5 XSCALE V6 V7 ALL ++ * V5 V5 V5 -- V6 V7 ALL ++ * XSCALE XSCALE -- XSCALE -- -- ALL ++ * V6 V6 V6 -- V6 V7 ALL ++ * V7 V7 V7 -- V7 V7 ALL ++ * ALL ALL ALL ALL ALL ALL ALL ++ */ ++ if((cpusubtype1 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM_ALL) ++ return(cpusubtype2); ++ if((cpusubtype2 & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM_ALL) ++ return(cpusubtype1); ++ switch((cpusubtype1 & ~CPU_SUBTYPE_MASK)){ ++ case CPU_SUBTYPE_ARM_V7: ++ switch((cpusubtype2 & ~CPU_SUBTYPE_MASK)){ ++ case CPU_SUBTYPE_ARM_XSCALE: ++ return((cpu_subtype_t)-1); ++ default: ++ return(CPU_SUBTYPE_ARM_V7); ++ } ++ case CPU_SUBTYPE_ARM_V6: ++ switch((cpusubtype2 & ~CPU_SUBTYPE_MASK)){ ++ case CPU_SUBTYPE_ARM_XSCALE: ++ return((cpu_subtype_t)-1); ++ default: ++ return(CPU_SUBTYPE_ARM_V6); ++ } ++ case CPU_SUBTYPE_ARM_XSCALE: ++ switch((cpusubtype2 & ~CPU_SUBTYPE_MASK)){ ++ case CPU_SUBTYPE_ARM_V7: ++ case CPU_SUBTYPE_ARM_V6: ++ case CPU_SUBTYPE_ARM_V5TEJ: ++ return((cpu_subtype_t)-1); ++ default: ++ return(CPU_SUBTYPE_ARM_XSCALE); ++ } ++ case CPU_SUBTYPE_ARM_V5TEJ: ++ switch((cpusubtype2 & ~CPU_SUBTYPE_MASK)){ ++ case CPU_SUBTYPE_ARM_XSCALE: ++ return((cpu_subtype_t)-1); ++ case CPU_SUBTYPE_ARM_V7: ++ return(CPU_SUBTYPE_ARM_V7); ++ case CPU_SUBTYPE_ARM_V6: ++ return(CPU_SUBTYPE_ARM_V6); ++ default: ++ return(CPU_SUBTYPE_ARM_V5TEJ); ++ } ++ case CPU_SUBTYPE_ARM_V4T: ++ return((cpusubtype2 & ~CPU_SUBTYPE_MASK)); ++ default: ++ return((cpu_subtype_t)-1); ++ } ++ + default: + return((cpu_subtype_t)-1); + } +Index: odcctools-9.2-ld/libmacho/get_end.c +=================================================================== +--- odcctools-9.2-ld.orig/libmacho/get_end.c 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/libmacho/get_end.c 2013-09-03 21:08:01.865209516 +0000 +@@ -25,13 +25,7 @@ + #include <mach-o/ldsyms.h> + #include <mach-o/getsect.h> + #ifndef __OPENSTEP__ +- +-#ifdef __LP64__ +-extern struct mach_header_64 *_NSGetMachExecuteHeader(void); +-#else /* !defined(__LP64__) */ + #include <crt_externs.h> +-#endif /* !defined(__LP64__) */ +- + #else /* defined(__OPENSTEP__) */ + #ifdef __DYNAMIC__ + #include "mach-o/dyld.h" /* defines _dyld_lookup_and_bind() */ +@@ -49,7 +43,7 @@ + #define SETUP_VAR(var) \ + if ( var ## _pointer == 0) { \ + _dyld_lookup_and_bind( STRINGIFY(_ ## var), \ +- (unsigned long *) & var ## _pointer, 0); \ ++ (uint32_t *) & var ## _pointer, 0); \ + } + #define USE_VAR(var) (* var ## _pointer) + #endif +@@ -70,13 +64,13 @@ + { + #ifndef __LP64__ + +- static struct mach_header *mhp = NULL; + struct segment_command *sgp; +- unsigned long i, _end; ++ unsigned long _end; ++ uint32_t i; + #ifndef __OPENSTEP__ +- if(mhp == NULL) +- mhp = _NSGetMachExecuteHeader(); ++ struct mach_header *mhp = _NSGetMachExecuteHeader(); + #else /* defined(__OPENSTEP__) */ ++ static struct mach_header *mhp = NULL; + DECLARE_VAR(_mh_execute_header, struct mach_header); + SETUP_VAR(_mh_execute_header); + +@@ -95,12 +89,11 @@ + + #else /* defined(__LP64__) */ + +- static struct mach_header_64 *mhp = NULL; ++ struct mach_header_64 *mhp = _NSGetMachExecuteHeader(); + struct segment_command_64 *sgp; +- unsigned long i, _end; ++ unsigned long _end; ++ uint32_t i; + +- if(mhp == NULL) +- mhp = _NSGetMachExecuteHeader(); + _end = 0; + sgp = (struct segment_command_64 *) + ((char *)mhp + sizeof(struct mach_header_64)); +Index: odcctools-9.2-ld/libmacho/getsecbyname.c +=================================================================== +--- odcctools-9.2-ld.orig/libmacho/getsecbyname.c 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/libmacho/getsecbyname.c 2013-09-03 21:08:01.865209516 +0000 +@@ -28,13 +28,7 @@ + #include <mach-o/dyld.h> /* defines _dyld_lookup_and_bind() */ + #endif /* defined(__DYNAMIC__) */ + #ifndef __OPENSTEP__ +- +-#ifdef __LP64__ +-extern struct mach_header_64 *_NSGetMachExecuteHeader(void); +-#else /* !defined(__LP64__) */ + #include <crt_externs.h> +-#endif /* !defined(__LP64__) */ +- + #else /* defined(__OPENSTEP__) */ + + #if !defined(__DYNAMIC__) +@@ -49,7 +43,7 @@ + #define SETUP_VAR(var) \ + if ( var ## _pointer == NULL) { \ + _dyld_lookup_and_bind( STRINGIFY(_ ## var), \ +- (unsigned long *) & var ## _pointer, NULL); \ ++ (uint32_t *) & var ## _pointer, NULL); \ + } + #define USE_VAR(var) (* var ## _pointer) + #endif +@@ -68,7 +62,7 @@ + { + struct segment_command *sgp; + struct section *sp; +- unsigned long i, j; ++ uint32_t i, j; + + sgp = (struct segment_command *) + ((char *)mhp + sizeof(struct mach_header)); +@@ -106,7 +100,7 @@ + { + struct segment_command_64 *sgp; + struct section_64 *sp; +- unsigned long i, j; ++ uint32_t i, j; + + sgp = (struct segment_command_64 *) + ((char *)mhp + sizeof(struct mach_header_64)); +@@ -147,12 +141,12 @@ + { + struct segment_command *sgp; + struct section *sp; +- unsigned long i, j; ++ uint32_t i, j; + + sgp = (struct segment_command *) + ((char *)mhp + sizeof(struct mach_header)); + for(i = 0; i < mhp->ncmds; i++){ +- if(sgp->cmd == (fSwap ? NXSwapLong(LC_SEGMENT) : LC_SEGMENT)) { ++ if(sgp->cmd == (fSwap ? OSSwapInt32(LC_SEGMENT) : LC_SEGMENT)) { + + if (fSwap) { + #ifdef __LITTLE_ENDIAN__ +@@ -188,7 +182,7 @@ + sgp = (struct segment_command *)((char *)sgp + sgp->cmdsize); + } else { + sgp = (struct segment_command *)((char *)sgp + +- (fSwap ? NXSwapLong(sgp->cmdsize) : sgp->cmdsize)); ++ (fSwap ? OSSwapInt32(sgp->cmdsize) : sgp->cmdsize)); + } + } + return((struct section *)0); +@@ -206,11 +200,10 @@ + const char *segname, + const char *sectname) + { +- static struct mach_header *mhp = NULL; + #ifndef __OPENSTEP__ +- if(mhp == NULL) +- mhp = _NSGetMachExecuteHeader(); ++ struct mach_header *mhp = _NSGetMachExecuteHeader(); + #else /* defined(__OPENSTEP__) */ ++ static struct mach_header *mhp = NULL; + DECLARE_VAR(_mh_execute_header, struct mach_header); + SETUP_VAR(_mh_execute_header); + mhp = (struct mach_header *)(& USE_VAR(_mh_execute_header)); +@@ -225,10 +218,8 @@ + const char *segname, + const char *sectname) + { +- static struct mach_header_64 *mhp = NULL; ++ struct mach_header_64 *mhp = _NSGetMachExecuteHeader(); + +- if(mhp == NULL) +- mhp = _NSGetMachExecuteHeader(); + return(getsectbynamefromheader_64(mhp, segname, sectname)); + } + +@@ -262,6 +253,185 @@ + } + + /* ++ * This routine returns the a pointer to the section contents of the named ++ * section in the named segment if it exists in the image pointed to by the ++ * mach header. Otherwise it returns zero. ++ */ ++#ifndef __LP64__ ++ ++uint8_t * ++getsectiondata( ++const struct mach_header *mhp, ++const char *segname, ++const char *sectname, ++unsigned long *size) ++{ ++ struct segment_command *sgp, *zero; ++ struct section *sp, *find; ++ uint32_t i, j; ++ ++ zero = 0; ++ find = 0; ++ sp = 0; ++ sgp = (struct segment_command *) ++ ((char *)mhp + sizeof(struct mach_header)); ++ for(i = 0; i < mhp->ncmds; i++){ ++ if(sgp->cmd == LC_SEGMENT){ ++ if(zero == 0 && sgp->fileoff == 0 && sgp->nsects != 0){ ++ zero = sgp; ++ if(find != 0) ++ goto done; ++ } ++ if(find == 0 && ++ strncmp(sgp->segname, segname, sizeof(sgp->segname)) == 0){ ++ sp = (struct section *)((char *)sgp + ++ sizeof(struct segment_command)); ++ for(j = 0; j < sgp->nsects; j++){ ++ if(strncmp(sp->sectname, sectname, ++ sizeof(sp->sectname)) == 0 && ++ strncmp(sp->segname, segname, ++ sizeof(sp->segname)) == 0){ ++ find = sp; ++ if(zero != 0) ++ goto done; ++ } ++ sp = (struct section *)((char *)sp + ++ sizeof(struct section)); ++ } ++ } ++ } ++ sgp = (struct segment_command *)((char *)sgp + sgp->cmdsize); ++ } ++ return(0); ++done: ++ *size = sp->size; ++ return((uint8_t *)((uintptr_t)mhp - zero->vmaddr + sp->addr)); ++} ++ ++uint8_t * ++getsegmentdata( ++const struct mach_header *mhp, ++const char *segname, ++unsigned long *size) ++{ ++ struct segment_command *sgp, *zero, *find; ++ uint32_t i; ++ ++ zero = 0; ++ find = 0; ++ sgp = (struct segment_command *) ++ ((char *)mhp + sizeof(struct mach_header)); ++ for(i = 0; i < mhp->ncmds; i++){ ++ if(sgp->cmd == LC_SEGMENT){ ++ if(zero == 0 && sgp->fileoff == 0 && sgp->nsects != 0){ ++ zero = sgp; ++ if(find != 0) ++ goto done; ++ } ++ if(find == 0 && ++ strncmp(sgp->segname, segname, sizeof(sgp->segname)) == 0){ ++ find = sgp; ++ if(zero != 0) ++ goto done; ++ } ++ } ++ sgp = (struct segment_command *)((char *)sgp + sgp->cmdsize); ++ } ++ return(0); ++done: ++ *size = sgp->vmsize; ++ return((uint8_t *)((uintptr_t)mhp - zero->vmaddr + sgp->vmaddr)); ++} ++ ++#else /* defined(__LP64__) */ ++ ++uint8_t * ++getsectiondata( ++const struct mach_header_64 *mhp, ++const char *segname, ++const char *sectname, ++unsigned long *size) ++{ ++ struct segment_command_64 *sgp, *zero; ++ struct section_64 *sp, *find; ++ uint32_t i, j; ++ ++ zero = 0; ++ find = 0; ++ sp = 0; ++ sgp = (struct segment_command_64 *) ++ ((char *)mhp + sizeof(struct mach_header_64)); ++ for(i = 0; i < mhp->ncmds; i++){ ++ if(sgp->cmd == LC_SEGMENT_64){ ++ if(zero == 0 && sgp->fileoff == 0 && sgp->nsects != 0){ ++ zero = sgp; ++ if(find != 0) ++ goto done; ++ } ++ if(find == 0 && ++ strncmp(sgp->segname, segname, sizeof(sgp->segname)) == 0){ ++ sp = (struct section_64 *)((char *)sgp + ++ sizeof(struct segment_command_64)); ++ for(j = 0; j < sgp->nsects; j++){ ++ if(strncmp(sp->sectname, sectname, ++ sizeof(sp->sectname)) == 0 && ++ strncmp(sp->segname, segname, ++ sizeof(sp->segname)) == 0){ ++ find = sp; ++ if(zero != 0) ++ goto done; ++ } ++ sp = (struct section_64 *)((char *)sp + ++ sizeof(struct section_64)); ++ } ++ } ++ } ++ sgp = (struct segment_command_64 *)((char *)sgp + sgp->cmdsize); ++ } ++ return(0); ++done: ++ *size = sp->size; ++ return((uint8_t *)((uintptr_t)mhp - zero->vmaddr + sp->addr)); ++} ++ ++uint8_t * ++getsegmentdata( ++const struct mach_header_64 *mhp, ++const char *segname, ++unsigned long *size) ++{ ++ struct segment_command_64 *sgp, *zero, *find; ++ uint32_t i; ++ ++ zero = 0; ++ find = 0; ++ sgp = (struct segment_command_64 *) ++ ((char *)mhp + sizeof(struct mach_header_64)); ++ for(i = 0; i < mhp->ncmds; i++){ ++ if(sgp->cmd == LC_SEGMENT_64){ ++ if(zero == 0 && sgp->fileoff == 0 && sgp->nsects != 0){ ++ zero = sgp; ++ if(find != 0) ++ goto done; ++ } ++ if(find == 0 && ++ strncmp(sgp->segname, segname, sizeof(sgp->segname)) == 0){ ++ find = sgp; ++ if(zero != 0) ++ goto done; ++ } ++ } ++ sgp = (struct segment_command_64 *)((char *)sgp + sgp->cmdsize); ++ } ++ return(0); ++done: ++ *size = sgp->vmsize; ++ return((uint8_t *)((uintptr_t)mhp - zero->vmaddr + sgp->vmaddr)); ++} ++ ++#endif /* defined(__LP64__) */ ++ ++/* + * This routine returns the a pointer to the data for the named section in the + * named segment if it exist in the mach header passed to it. Also it returns + * the size of the section data indirectly through the pointer size. Otherwise +@@ -282,7 +452,7 @@ + return(NULL); + } + *size = sp->size; +- return((char *)((unsigned long)(sp->addr))); ++ return((char *)((uintptr_t)(sp->addr))); + } + + /* +@@ -306,7 +476,7 @@ + return(NULL); + } + *size = sp->size; +- return((char *)((unsigned long)(sp->addr))); ++ return((char *)((uintptr_t)(sp->addr))); + } + + #ifdef __DYNAMIC__ +@@ -324,7 +494,8 @@ + const char *sectname, + unsigned long *size) + { +- unsigned long i, n, vmaddr_slide; ++ uint32_t i, n; ++ uintptr_t vmaddr_slide; + #ifndef __LP64__ + struct mach_header *mh; + const struct section *s; +Index: odcctools-9.2-ld/libmacho/getsegbyname.c +=================================================================== +--- odcctools-9.2-ld.orig/libmacho/getsegbyname.c 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/libmacho/getsegbyname.c 2013-09-03 21:08:01.869209516 +0000 +@@ -25,11 +25,7 @@ + #ifndef __OPENSTEP__ + + #ifndef RLD +-#ifdef __LP64__ +-extern struct mach_header_64 *_NSGetMachExecuteHeader(void); +-#else /* !defined(__LP64__) */ + #include <crt_externs.h> +-#endif /* !defined(__LP64__) */ + #endif /* !defined(RLD) */ + + #else /* defined(__OPENSTEP__) */ +@@ -49,7 +45,7 @@ + #define SETUP_VAR(var) \ + if ( var ## _pointer == 0) { \ + _dyld_lookup_and_bind( STRINGIFY(_ ## var), \ +- (unsigned long *) & var ## _pointer, 0); \ ++ (uint32_t *) & var ## _pointer, 0); \ + } + #define USE_VAR(var) (* var ## _pointer) + #endif +@@ -68,14 +64,13 @@ + getsegbyname( + char *segname) + { +- static struct mach_header *mhp = NULL; + struct segment_command *sgp; +- unsigned long i; ++ uint32_t i; + #ifndef RLD + #ifndef __OPENSTEP__ +- if(mhp == NULL) +- mhp = _NSGetMachExecuteHeader(); ++ struct mach_header *mhp = _NSGetMachExecuteHeader(); + #else /* defined(__OPENSTEP__) */ ++ static struct mach_header *mhp = NULL; + DECLARE_VAR(_mh_execute_header, struct mach_header); + SETUP_VAR(_mh_execute_header); + mhp = (struct mach_header *)(& USE_VAR(_mh_execute_header)); +@@ -101,15 +96,14 @@ + getsegbyname( + char *segname) + { +- static struct mach_header_64 *mhp = NULL; ++ struct mach_header_64 *mhp = NULL; + struct segment_command_64 *sgp; +- unsigned long i; ++ uint32_t i; + +- if(mhp == NULL) + #ifndef RLD +- mhp = _NSGetMachExecuteHeader(); ++ mhp = _NSGetMachExecuteHeader(); + #else /* defined(RLD) */ +- mhp = (struct mach_header_64 *)(&_mh_execute_header); ++ mhp = (struct mach_header_64 *)(&_mh_execute_header); + #endif /* defined(RLD) */ + + sgp = (struct segment_command_64 *) +Index: odcctools-9.2-ld/libmacho/i386_swap.c +=================================================================== +--- odcctools-9.2-ld.orig/libmacho/i386_swap.c 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/libmacho/i386_swap.c 2013-09-03 21:08:01.869209516 +0000 +@@ -132,6 +132,7 @@ + #define __dr7 dr7 + + #include <string.h> ++#include <libkern/OSByteOrder.h> + #include <mach-o/i386/swap.h> + + void +@@ -139,22 +140,22 @@ + i386_thread_state_t *cpu, + enum NXByteOrder target_byte_sex) + { +- cpu->eax = NXSwapLong(cpu->eax); +- cpu->ebx = NXSwapLong(cpu->ebx); +- cpu->ecx = NXSwapLong(cpu->ecx); +- cpu->edx = NXSwapLong(cpu->edx); +- cpu->edi = NXSwapLong(cpu->edi); +- cpu->esi = NXSwapLong(cpu->esi); +- cpu->ebp = NXSwapLong(cpu->ebp); +- cpu->esp = NXSwapLong(cpu->esp); +- cpu->ss = NXSwapLong(cpu->ss); +- cpu->eflags = NXSwapLong(cpu->eflags); +- cpu->eip = NXSwapLong(cpu->eip); +- cpu->cs = NXSwapLong(cpu->cs); +- cpu->ds = NXSwapLong(cpu->ds); +- cpu->es = NXSwapLong(cpu->es); +- cpu->fs = NXSwapLong(cpu->fs); +- cpu->gs = NXSwapLong(cpu->gs); ++ cpu->eax = OSSwapInt32(cpu->eax); ++ cpu->ebx = OSSwapInt32(cpu->ebx); ++ cpu->ecx = OSSwapInt32(cpu->ecx); ++ cpu->edx = OSSwapInt32(cpu->edx); ++ cpu->edi = OSSwapInt32(cpu->edi); ++ cpu->esi = OSSwapInt32(cpu->esi); ++ cpu->ebp = OSSwapInt32(cpu->ebp); ++ cpu->esp = OSSwapInt32(cpu->esp); ++ cpu->ss = OSSwapInt32(cpu->ss); ++ cpu->eflags = OSSwapInt32(cpu->eflags); ++ cpu->eip = OSSwapInt32(cpu->eip); ++ cpu->cs = OSSwapInt32(cpu->cs); ++ cpu->ds = OSSwapInt32(cpu->ds); ++ cpu->es = OSSwapInt32(cpu->es); ++ cpu->fs = OSSwapInt32(cpu->fs); ++ cpu->gs = OSSwapInt32(cpu->gs); + } + + #ifdef x86_THREAD_STATE64 +@@ -163,27 +164,27 @@ + x86_thread_state64_t *cpu, + enum NXByteOrder target_byte_sex) + { +- cpu->rax = NXSwapLongLong(cpu->rax); +- cpu->rbx = NXSwapLongLong(cpu->rbx); +- cpu->rcx = NXSwapLongLong(cpu->rcx); +- cpu->rdx = NXSwapLongLong(cpu->rdx); +- cpu->rdi = NXSwapLongLong(cpu->rdi); +- cpu->rsi = NXSwapLongLong(cpu->rsi); +- cpu->rbp = NXSwapLongLong(cpu->rbp); +- cpu->rsp = NXSwapLongLong(cpu->rsp); +- cpu->rflags = NXSwapLongLong(cpu->rflags); +- cpu->rip = NXSwapLongLong(cpu->rip); +- cpu->r8 = NXSwapLongLong(cpu->r8); +- cpu->r9 = NXSwapLongLong(cpu->r9); +- cpu->r10 = NXSwapLongLong(cpu->r10); +- cpu->r11 = NXSwapLongLong(cpu->r11); +- cpu->r12 = NXSwapLongLong(cpu->r12); +- cpu->r13 = NXSwapLongLong(cpu->r13); +- cpu->r14 = NXSwapLongLong(cpu->r14); +- cpu->r15 = NXSwapLongLong(cpu->r15); +- cpu->cs = NXSwapLongLong(cpu->cs); +- cpu->fs = NXSwapLongLong(cpu->fs); +- cpu->gs = NXSwapLongLong(cpu->gs); ++ cpu->rax = OSSwapInt64(cpu->rax); ++ cpu->rbx = OSSwapInt64(cpu->rbx); ++ cpu->rcx = OSSwapInt64(cpu->rcx); ++ cpu->rdx = OSSwapInt64(cpu->rdx); ++ cpu->rdi = OSSwapInt64(cpu->rdi); ++ cpu->rsi = OSSwapInt64(cpu->rsi); ++ cpu->rbp = OSSwapInt64(cpu->rbp); ++ cpu->rsp = OSSwapInt64(cpu->rsp); ++ cpu->rflags = OSSwapInt64(cpu->rflags); ++ cpu->rip = OSSwapInt64(cpu->rip); ++ cpu->r8 = OSSwapInt64(cpu->r8); ++ cpu->r9 = OSSwapInt64(cpu->r9); ++ cpu->r10 = OSSwapInt64(cpu->r10); ++ cpu->r11 = OSSwapInt64(cpu->r11); ++ cpu->r12 = OSSwapInt64(cpu->r12); ++ cpu->r13 = OSSwapInt64(cpu->r13); ++ cpu->r14 = OSSwapInt64(cpu->r14); ++ cpu->r15 = OSSwapInt64(cpu->r15); ++ cpu->cs = OSSwapInt64(cpu->cs); ++ cpu->fs = OSSwapInt64(cpu->fs); ++ cpu->gs = OSSwapInt64(cpu->gs); + } + + void +@@ -191,8 +192,8 @@ + x86_state_hdr_t *hdr, + enum NXByteOrder target_byte_sex) + { +- hdr->flavor = NXSwapLong(hdr->flavor); +- hdr->count = NXSwapLong(hdr->count); ++ hdr->flavor = OSSwapInt32(hdr->flavor); ++ hdr->count = OSSwapInt32(hdr->count); + } + + void +@@ -247,13 +248,13 @@ + + host_byte_sex = NXHostByteOrder(); + +- fpu->fpu_reserved[0] = NXSwapLong(fpu->fpu_reserved[0]); +- fpu->fpu_reserved[1] = NXSwapLong(fpu->fpu_reserved[1]); ++ fpu->fpu_reserved[0] = OSSwapInt32(fpu->fpu_reserved[0]); ++ fpu->fpu_reserved[1] = OSSwapInt32(fpu->fpu_reserved[1]); + + if(target_byte_sex == host_byte_sex){ + memcpy(&sfpc, &(fpu->fpu_fcw), + sizeof(struct swapped_fp_control)); +- sfpc.u.half = NXSwapShort(sfpc.u.half); ++ sfpc.u.half = OSSwapInt16(sfpc.u.half); + fpu->fpu_fcw.rc = sfpc.u.fields.rc; + fpu->fpu_fcw.pc = sfpc.u.fields.pc; + fpu->fpu_fcw.precis = sfpc.u.fields.precis; +@@ -265,7 +266,7 @@ + + memcpy(&sfps, &(fpu->fpu_fsw), + sizeof(struct swapped_fp_status)); +- sfps.u.half = NXSwapShort(sfps.u.half); ++ sfps.u.half = OSSwapInt16(sfps.u.half); + fpu->fpu_fsw.busy = sfps.u.fields.busy; + fpu->fpu_fsw.c3 = sfps.u.fields.c3; + fpu->fpu_fsw.tos = sfps.u.fields.tos; +@@ -290,7 +291,7 @@ + sfpc.u.fields.zdiv = fpu->fpu_fcw.zdiv; + sfpc.u.fields.denorm = fpu->fpu_fcw.denorm; + sfpc.u.fields.invalid = fpu->fpu_fcw.invalid; +- sfpc.u.half = NXSwapShort(sfpc.u.half); ++ sfpc.u.half = OSSwapInt16(sfpc.u.half); + memcpy(&(fpu->fpu_fcw), &sfpc, + sizeof(struct swapped_fp_control)); + +@@ -308,20 +309,20 @@ + sfps.u.fields.zdiv = fpu->fpu_fsw.zdiv; + sfps.u.fields.denorm = fpu->fpu_fsw.denorm; + sfps.u.fields.invalid = fpu->fpu_fsw.invalid; +- sfps.u.half = NXSwapShort(sfps.u.half); ++ sfps.u.half = OSSwapInt16(sfps.u.half); + memcpy(&(fpu->fpu_fsw), &sfps, + sizeof(struct swapped_fp_status)); + } +- fpu->fpu_fop = NXSwapShort(fpu->fpu_fop); +- fpu->fpu_ip = NXSwapLong(fpu->fpu_ip); +- fpu->fpu_cs = NXSwapShort(fpu->fpu_cs); +- fpu->fpu_rsrv2 = NXSwapShort(fpu->fpu_rsrv2); +- fpu->fpu_dp = NXSwapLong(fpu->fpu_dp); +- fpu->fpu_ds = NXSwapShort(fpu->fpu_ds); +- fpu->fpu_rsrv3 = NXSwapShort(fpu->fpu_rsrv3); +- fpu->fpu_mxcsr = NXSwapLong(fpu->fpu_mxcsr); +- fpu->fpu_mxcsrmask = NXSwapLong(fpu->fpu_mxcsrmask); +- fpu->fpu_reserved1 = NXSwapLong(fpu->fpu_reserved1); ++ fpu->fpu_fop = OSSwapInt16(fpu->fpu_fop); ++ fpu->fpu_ip = OSSwapInt32(fpu->fpu_ip); ++ fpu->fpu_cs = OSSwapInt16(fpu->fpu_cs); ++ fpu->fpu_rsrv2 = OSSwapInt16(fpu->fpu_rsrv2); ++ fpu->fpu_dp = OSSwapInt32(fpu->fpu_dp); ++ fpu->fpu_ds = OSSwapInt16(fpu->fpu_ds); ++ fpu->fpu_rsrv3 = OSSwapInt16(fpu->fpu_rsrv3); ++ fpu->fpu_mxcsr = OSSwapInt32(fpu->fpu_mxcsr); ++ fpu->fpu_mxcsrmask = OSSwapInt32(fpu->fpu_mxcsrmask); ++ fpu->fpu_reserved1 = OSSwapInt32(fpu->fpu_reserved1); + } + + void +@@ -329,9 +330,9 @@ + x86_exception_state64_t *exc, + enum NXByteOrder target_byte_sex) + { +- exc->trapno = NXSwapLong(exc->trapno); +- exc->err = NXSwapLong(exc->err); +- exc->faultvaddr = NXSwapLongLong(exc->faultvaddr); ++ exc->trapno = OSSwapInt32(exc->trapno); ++ exc->err = OSSwapInt32(exc->err); ++ exc->faultvaddr = OSSwapInt64(exc->faultvaddr); + } + + void +@@ -370,9 +371,13 @@ + + swap_x86_state_hdr(&fpu->fsh, target_byte_sex); + ++/* current i386 thread states */ ++#if i386_THREAD_STATE == 1 + if(hdr.flavor == x86_FLOAT_STATE32) + swap_i386_float_state(&fpu->ufs.fs32, target_byte_sex); +- else if(hdr.flavor == x86_FLOAT_STATE64) ++ else ++#endif ++ if(hdr.flavor == x86_FLOAT_STATE64) + swap_x86_float_state64(&fpu->ufs.fs64, target_byte_sex); + } + +@@ -391,9 +396,13 @@ + + swap_x86_state_hdr(&exc->esh, target_byte_sex); + ++/* current i386 thread states */ ++#if i386_THREAD_STATE == 1 + if(hdr.flavor == x86_EXCEPTION_STATE32) + swap_i386_exception_state(&exc->ues.es32, target_byte_sex); +- else if(hdr.flavor == x86_EXCEPTION_STATE64) ++ else ++#endif ++ if(hdr.flavor == x86_EXCEPTION_STATE64) + swap_x86_exception_state64(&exc->ues.es64, target_byte_sex); + } + +@@ -402,14 +411,14 @@ + x86_debug_state32_t *debug, + enum NXByteOrder target_byte_sex) + { +- debug->dr0 = NXSwapLong(debug->dr0); +- debug->dr1 = NXSwapLong(debug->dr1); +- debug->dr2 = NXSwapLong(debug->dr2); +- debug->dr3 = NXSwapLong(debug->dr3); +- debug->dr4 = NXSwapLong(debug->dr4); +- debug->dr5 = NXSwapLong(debug->dr5); +- debug->dr6 = NXSwapLong(debug->dr6); +- debug->dr7 = NXSwapLong(debug->dr7); ++ debug->dr0 = OSSwapInt32(debug->dr0); ++ debug->dr1 = OSSwapInt32(debug->dr1); ++ debug->dr2 = OSSwapInt32(debug->dr2); ++ debug->dr3 = OSSwapInt32(debug->dr3); ++ debug->dr4 = OSSwapInt32(debug->dr4); ++ debug->dr5 = OSSwapInt32(debug->dr5); ++ debug->dr6 = OSSwapInt32(debug->dr6); ++ debug->dr7 = OSSwapInt32(debug->dr7); + } + + void +@@ -417,14 +426,14 @@ + x86_debug_state64_t *debug, + enum NXByteOrder target_byte_sex) + { +- debug->dr0 = NXSwapLongLong(debug->dr0); +- debug->dr1 = NXSwapLongLong(debug->dr1); +- debug->dr2 = NXSwapLongLong(debug->dr2); +- debug->dr3 = NXSwapLongLong(debug->dr3); +- debug->dr4 = NXSwapLongLong(debug->dr4); +- debug->dr5 = NXSwapLongLong(debug->dr5); +- debug->dr6 = NXSwapLongLong(debug->dr6); +- debug->dr7 = NXSwapLongLong(debug->dr7); ++ debug->dr0 = OSSwapInt64(debug->dr0); ++ debug->dr1 = OSSwapInt64(debug->dr1); ++ debug->dr2 = OSSwapInt64(debug->dr2); ++ debug->dr3 = OSSwapInt64(debug->dr3); ++ debug->dr4 = OSSwapInt64(debug->dr4); ++ debug->dr5 = OSSwapInt64(debug->dr5); ++ debug->dr6 = OSSwapInt64(debug->dr6); ++ debug->dr7 = OSSwapInt64(debug->dr7); + } + + void +@@ -506,13 +515,13 @@ + + host_byte_sex = NXHostByteOrder(); + +- fpu->fpu_reserved[0] = NXSwapLong(fpu->fpu_reserved[0]); +- fpu->fpu_reserved[1] = NXSwapLong(fpu->fpu_reserved[1]); ++ fpu->fpu_reserved[0] = OSSwapInt32(fpu->fpu_reserved[0]); ++ fpu->fpu_reserved[1] = OSSwapInt32(fpu->fpu_reserved[1]); + + if(target_byte_sex == host_byte_sex){ + memcpy(&sfpc, &(fpu->fpu_fcw), + sizeof(struct swapped_fp_control)); +- sfpc.u.half = NXSwapShort(sfpc.u.half); ++ sfpc.u.half = OSSwapInt16(sfpc.u.half); + fpu->fpu_fcw.rc = sfpc.u.fields.rc; + fpu->fpu_fcw.pc = sfpc.u.fields.pc; + fpu->fpu_fcw.precis = sfpc.u.fields.precis; +@@ -524,7 +533,7 @@ + + memcpy(&sfps, &(fpu->fpu_fsw), + sizeof(struct swapped_fp_status)); +- sfps.u.half = NXSwapShort(sfps.u.half); ++ sfps.u.half = OSSwapInt16(sfps.u.half); + fpu->fpu_fsw.busy = sfps.u.fields.busy; + fpu->fpu_fsw.c3 = sfps.u.fields.c3; + fpu->fpu_fsw.tos = sfps.u.fields.tos; +@@ -549,7 +558,7 @@ + sfpc.u.fields.zdiv = fpu->fpu_fcw.zdiv; + sfpc.u.fields.denorm = fpu->fpu_fcw.denorm; + sfpc.u.fields.invalid = fpu->fpu_fcw.invalid; +- sfpc.u.half = NXSwapShort(sfpc.u.half); ++ sfpc.u.half = OSSwapInt16(sfpc.u.half); + memcpy(&(fpu->fpu_fcw), &sfpc, + sizeof(struct swapped_fp_control)); + +@@ -567,20 +576,20 @@ + sfps.u.fields.zdiv = fpu->fpu_fsw.zdiv; + sfps.u.fields.denorm = fpu->fpu_fsw.denorm; + sfps.u.fields.invalid = fpu->fpu_fsw.invalid; +- sfps.u.half = NXSwapShort(sfps.u.half); ++ sfps.u.half = OSSwapInt16(sfps.u.half); + memcpy(&(fpu->fpu_fsw), &sfps, + sizeof(struct swapped_fp_status)); + } +- fpu->fpu_fop = NXSwapShort(fpu->fpu_fop); +- fpu->fpu_ip = NXSwapLong(fpu->fpu_ip); +- fpu->fpu_cs = NXSwapShort(fpu->fpu_cs); +- fpu->fpu_rsrv2 = NXSwapShort(fpu->fpu_rsrv2); +- fpu->fpu_dp = NXSwapLong(fpu->fpu_dp); +- fpu->fpu_ds = NXSwapShort(fpu->fpu_ds); +- fpu->fpu_rsrv3 = NXSwapShort(fpu->fpu_rsrv3); +- fpu->fpu_mxcsr = NXSwapLong(fpu->fpu_mxcsr); +- fpu->fpu_mxcsrmask = NXSwapLong(fpu->fpu_mxcsrmask); +- fpu->fpu_reserved1 = NXSwapLong(fpu->fpu_reserved1); ++ fpu->fpu_fop = OSSwapInt16(fpu->fpu_fop); ++ fpu->fpu_ip = OSSwapInt32(fpu->fpu_ip); ++ fpu->fpu_cs = OSSwapInt16(fpu->fpu_cs); ++ fpu->fpu_rsrv2 = OSSwapInt16(fpu->fpu_rsrv2); ++ fpu->fpu_dp = OSSwapInt32(fpu->fpu_dp); ++ fpu->fpu_ds = OSSwapInt16(fpu->fpu_ds); ++ fpu->fpu_rsrv3 = OSSwapInt16(fpu->fpu_rsrv3); ++ fpu->fpu_mxcsr = OSSwapInt32(fpu->fpu_mxcsr); ++ fpu->fpu_mxcsrmask = OSSwapInt32(fpu->fpu_mxcsrmask); ++ fpu->fpu_reserved1 = OSSwapInt32(fpu->fpu_reserved1); + + #endif /* !defined(i386_EXCEPTION_STATE_COUNT) */ + } +@@ -590,9 +599,9 @@ + i386_exception_state_t *exc, + enum NXByteOrder target_byte_sex) + { +- exc->trapno = NXSwapLong(exc->trapno); +- exc->err = NXSwapLong(exc->err); +- exc->faultvaddr = NXSwapLong(exc->faultvaddr); ++ exc->trapno = OSSwapInt32(exc->trapno); ++ exc->err = OSSwapInt32(exc->err); ++ exc->faultvaddr = OSSwapInt32(exc->faultvaddr); + } + #endif /* i386_THREAD_STATE == 1 */ + +@@ -690,18 +699,18 @@ + } ss; + + enum NXByteOrder host_byte_sex; +- unsigned long i; ++ int i; + + host_byte_sex = NXHostByteOrder(); + +- fpu->environ.ip = NXSwapLong(fpu->environ.ip); +- fpu->environ.opcode = NXSwapShort(fpu->environ.opcode); +- fpu->environ.dp = NXSwapLong(fpu->environ.dp); ++ fpu->environ.ip = OSSwapInt32(fpu->environ.ip); ++ fpu->environ.opcode = OSSwapInt16(fpu->environ.opcode); ++ fpu->environ.dp = OSSwapInt32(fpu->environ.dp); + + if(target_byte_sex == host_byte_sex){ + memcpy(&sfpc, &(fpu->environ.control), + sizeof(struct swapped_fp_control)); +- sfpc.u.half = NXSwapShort(sfpc.u.half); ++ sfpc.u.half = OSSwapInt16(sfpc.u.half); + fpu->environ.control.rc = sfpc.u.fields.rc; + fpu->environ.control.pc = sfpc.u.fields.pc; + fpu->environ.control.precis = sfpc.u.fields.precis; +@@ -713,7 +722,7 @@ + + memcpy(&sfps, &(fpu->environ.status), + sizeof(struct swapped_fp_status)); +- sfps.u.half = NXSwapShort(sfps.u.half); ++ sfps.u.half = OSSwapInt16(sfps.u.half); + fpu->environ.status.busy = sfps.u.fields.busy; + fpu->environ.status.c3 = sfps.u.fields.c3; + fpu->environ.status.tos = sfps.u.fields.tos; +@@ -731,7 +740,7 @@ + + memcpy(&sfpt, &(fpu->environ.tag), + sizeof(struct swapped_fp_tag)); +- sfpt.u.half = NXSwapShort(sfpt.u.half); ++ sfpt.u.half = OSSwapInt16(sfpt.u.half); + fpu->environ.tag.tag7 = sfpt.u.fields.tag7; + fpu->environ.tag.tag6 = sfpt.u.fields.tag6; + fpu->environ.tag.tag5 = sfpt.u.fields.tag5; +@@ -743,14 +752,14 @@ + + memcpy(&ss, &(fpu->environ.cs), + sizeof(struct swapped_sel)); +- ss.u.half = NXSwapShort(ss.u.half); ++ ss.u.half = OSSwapInt16(ss.u.half); + fpu->environ.cs.index = ss.u.fields.index; + fpu->environ.cs.ti = ss.u.fields.ti; + fpu->environ.cs.rpl = ss.u.fields.rpl; + + memcpy(&ss, &(fpu->environ.ds), + sizeof(struct swapped_sel)); +- ss.u.half = NXSwapShort(ss.u.half); ++ ss.u.half = OSSwapInt16(ss.u.half); + fpu->environ.ds.index = ss.u.fields.index; + fpu->environ.ds.ti = ss.u.fields.ti; + fpu->environ.ds.rpl = ss.u.fields.rpl; +@@ -758,11 +767,11 @@ + for(i = 0; i < 8; i++){ + memcpy(&sfpd, &(fpu->stack.ST[i]), + sizeof(struct swapped_fp_data_reg)); +- fpu->stack.ST[i].mant = NXSwapShort(sfpd.mant); +- fpu->stack.ST[i].mant1 = NXSwapShort(sfpd.mant1); +- fpu->stack.ST[i].mant2 = NXSwapShort(sfpd.mant2); +- fpu->stack.ST[i].mant3 = NXSwapShort(sfpd.mant3); +- sfpd.u.half = NXSwapShort(sfpd.u.half); ++ fpu->stack.ST[i].mant = OSSwapInt16(sfpd.mant); ++ fpu->stack.ST[i].mant1 = OSSwapInt16(sfpd.mant1); ++ fpu->stack.ST[i].mant2 = OSSwapInt16(sfpd.mant2); ++ fpu->stack.ST[i].mant3 = OSSwapInt16(sfpd.mant3); ++ sfpd.u.half = OSSwapInt16(sfpd.u.half); + fpu->stack.ST[i].exp = sfpd.u.fields.exp; + fpu->stack.ST[i].sign = sfpd.u.fields.sign; + } +@@ -776,7 +785,7 @@ + sfpc.u.fields.zdiv = fpu->environ.control.zdiv; + sfpc.u.fields.denorm = fpu->environ.control.denorm; + sfpc.u.fields.invalid = fpu->environ.control.invalid; +- sfpc.u.half = NXSwapShort(sfpc.u.half); ++ sfpc.u.half = OSSwapInt16(sfpc.u.half); + memcpy(&(fpu->environ.control), &sfpc, + sizeof(struct swapped_fp_control)); + +@@ -794,7 +803,7 @@ + sfps.u.fields.zdiv = fpu->environ.status.zdiv; + sfps.u.fields.denorm = fpu->environ.status.denorm; + sfps.u.fields.invalid = fpu->environ.status.invalid; +- sfps.u.half = NXSwapShort(sfps.u.half); ++ sfps.u.half = OSSwapInt16(sfps.u.half); + memcpy(&(fpu->environ.status), &sfps, + sizeof(struct swapped_fp_status)); + +@@ -806,32 +815,32 @@ + sfpt.u.fields.tag2 = fpu->environ.tag.tag2; + sfpt.u.fields.tag1 = fpu->environ.tag.tag1; + sfpt.u.fields.tag0 = fpu->environ.tag.tag0; +- sfpt.u.half = NXSwapShort(sfpt.u.half); ++ sfpt.u.half = OSSwapInt16(sfpt.u.half); + memcpy(&(fpu->environ.tag), &sfpt, + sizeof(struct swapped_fp_tag)); + + ss.u.fields.index = fpu->environ.cs.index; + ss.u.fields.ti = fpu->environ.cs.ti; + ss.u.fields.rpl = fpu->environ.cs.rpl; +- ss.u.half = NXSwapShort(ss.u.half); ++ ss.u.half = OSSwapInt16(ss.u.half); + memcpy(&(fpu->environ.cs), &ss, + sizeof(struct swapped_sel)); + + ss.u.fields.index = fpu->environ.ds.index; + ss.u.fields.ti = fpu->environ.ds.ti; + ss.u.fields.rpl = fpu->environ.ds.rpl; +- ss.u.half = NXSwapShort(ss.u.half); ++ ss.u.half = OSSwapInt16(ss.u.half); + memcpy(&(fpu->environ.cs), &ss, + sizeof(struct swapped_sel)); + + for(i = 0; i < 8; i++){ +- sfpd.mant = NXSwapShort(fpu->stack.ST[i].mant); +- sfpd.mant1 = NXSwapShort(fpu->stack.ST[i].mant1); +- sfpd.mant2 = NXSwapShort(fpu->stack.ST[i].mant2); +- sfpd.mant3 = NXSwapShort(fpu->stack.ST[i].mant3); ++ sfpd.mant = OSSwapInt16(fpu->stack.ST[i].mant); ++ sfpd.mant1 = OSSwapInt16(fpu->stack.ST[i].mant1); ++ sfpd.mant2 = OSSwapInt16(fpu->stack.ST[i].mant2); ++ sfpd.mant3 = OSSwapInt16(fpu->stack.ST[i].mant3); + sfpd.u.fields.exp = fpu->stack.ST[i].exp; + sfpd.u.fields.sign = fpu->stack.ST[i].sign; +- sfpd.u.half = NXSwapShort(sfpd.u.half); ++ sfpd.u.half = OSSwapInt16(sfpd.u.half); + memcpy(&(fpu->stack.ST[i]), &sfpd, + sizeof(struct swapped_fp_data_reg)); + } +@@ -857,19 +866,19 @@ + wrtflt :1, + prot :1; + } pgfault; +- unsigned long word; ++ uint32_t word; + } u; + } sec; +- unsigned long word; ++ uint32_t word; + enum NXByteOrder host_byte_sex; + + host_byte_sex = NXHostByteOrder(); + +- exc->trapno = NXSwapLong(exc->trapno); ++ exc->trapno = OSSwapInt32(exc->trapno); + if(exc->trapno == 14){ + if(target_byte_sex == host_byte_sex){ + memcpy(&sec, &(exc->err), sizeof(struct swapped_err_code)); +- sec.u.word = NXSwapLong(sec.u.word); ++ sec.u.word = OSSwapInt32(sec.u.word); + exc->err.pgfault.user = sec.u.pgfault.user; + exc->err.pgfault.wrtflt = sec.u.pgfault.wrtflt; + exc->err.pgfault.prot = sec.u.pgfault.prot; +@@ -878,16 +887,16 @@ + sec.u.pgfault.prot = exc->err.pgfault.prot; + sec.u.pgfault.wrtflt = exc->err.pgfault.wrtflt; + sec.u.pgfault.user = exc->err.pgfault.user; +- sec.u.word = NXSwapLong(sec.u.word); ++ sec.u.word = OSSwapInt32(sec.u.word); + memcpy(&(exc->err), &sec, sizeof(struct swapped_err_code)); + } + } + else{ + if(target_byte_sex == host_byte_sex){ + memcpy(&sec, &(exc->err), sizeof(struct swapped_err_code)); +- sec.u.word = NXSwapLong(sec.u.word); ++ sec.u.word = OSSwapInt32(sec.u.word); + word = sec.u.normal.index; +- exc->err.normal.index = NXSwapLong(word); ++ exc->err.normal.index = OSSwapInt32(word); + exc->err.normal.tbl = sec.u.normal.tbl; + exc->err.normal.ext = sec.u.normal.ext; + } +@@ -895,8 +904,8 @@ + sec.u.normal.ext = exc->err.normal.ext; + sec.u.normal.tbl = exc->err.normal.tbl; + word = exc->err.normal.index; +- sec.u.normal.index = NXSwapLong(word); +- sec.u.word = NXSwapLong(sec.u.word); ++ sec.u.normal.index = OSSwapInt32(word); ++ sec.u.word = OSSwapInt32(sec.u.word); + memcpy(&(exc->err), &sec, sizeof(struct swapped_err_code)); + } + } +@@ -907,7 +916,7 @@ + i386_thread_cthreadstate_t *user, + enum NXByteOrder target_byte_sex) + { +- user->self = NXSwapLong(user->self); ++ user->self = OSSwapInt32(user->self); + } + #endif /* i386_THREAD_STATE == -1 */ + #endif /* !defined(RLD) */ +Index: odcctools-9.2-ld/libmacho/i860_swap.c +=================================================================== +--- odcctools-9.2-ld.orig/libmacho/i860_swap.c 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/libmacho/i860_swap.c 2013-09-03 21:08:01.873209515 +0000 +@@ -28,34 +28,34 @@ + struct i860_thread_state_regs *cpu, + enum NXByteOrder target_byte_sex) + { +- unsigned long i; ++ int i; + + for(i = 0; i < 31; i++) +- cpu->ireg[i] = NXSwapLong(cpu->ireg[i]); ++ cpu->ireg[i] = OSSwapInt32(cpu->ireg[i]); + for(i = 0; i < 30; i++) +- cpu->freg[i] = NXSwapLong(cpu->freg[i]); +- cpu->psr = NXSwapLong(cpu->psr); +- cpu->epsr = NXSwapLong(cpu->epsr); +- cpu->db = NXSwapLong(cpu->db); +- cpu->pc = NXSwapLong(cpu->pc); +- cpu->_padding_ = NXSwapLong(cpu->_padding_); +- cpu->Mres3 = NXSwapDouble(cpu->Mres3); +- cpu->Ares3 = NXSwapDouble(cpu->Ares3); +- cpu->Mres2 = NXSwapDouble(cpu->Mres2); +- cpu->Ares2 = NXSwapDouble(cpu->Ares2); +- cpu->Mres1 = NXSwapDouble(cpu->Mres1); +- cpu->Ares1 = NXSwapDouble(cpu->Ares1); +- cpu->Ires1 = NXSwapDouble(cpu->Ires1); +- cpu->Lres3m = NXSwapDouble(cpu->Lres3m); +- cpu->Lres2m = NXSwapDouble(cpu->Lres2m); +- cpu->Lres1m = NXSwapDouble(cpu->Lres1m); +- cpu->KR = NXSwapDouble(cpu->KR); +- cpu->KI = NXSwapDouble(cpu->KI); +- cpu->T = NXSwapDouble(cpu->T); +- cpu->Fsr3 = NXSwapLong(cpu->Fsr3); +- cpu->Fsr2 = NXSwapLong(cpu->Fsr2); +- cpu->Fsr1 = NXSwapLong(cpu->Fsr1); +- cpu->Mergelo32 = NXSwapLong(cpu->Mergelo32); +- cpu->Mergehi32 = NXSwapLong(cpu->Mergehi32); ++ cpu->freg[i] = OSSwapInt32(cpu->freg[i]); ++ cpu->psr = OSSwapInt32(cpu->psr); ++ cpu->epsr = OSSwapInt32(cpu->epsr); ++ cpu->db = OSSwapInt32(cpu->db); ++ cpu->pc = OSSwapInt32(cpu->pc); ++ cpu->_padding_ = OSSwapInt32(cpu->_padding_); ++ cpu->Mres3 = OSSwapInt64(cpu->Mres3); ++ cpu->Ares3 = OSSwapInt64(cpu->Ares3); ++ cpu->Mres2 = OSSwapInt64(cpu->Mres2); ++ cpu->Ares2 = OSSwapInt64(cpu->Ares2); ++ cpu->Mres1 = OSSwapInt64(cpu->Mres1); ++ cpu->Ares1 = OSSwapInt64(cpu->Ares1); ++ cpu->Ires1 = OSSwapInt64(cpu->Ires1); ++ cpu->Lres3m = OSSwapInt64(cpu->Lres3m); ++ cpu->Lres2m = OSSwapInt64(cpu->Lres2m); ++ cpu->Lres1m = OSSwapInt64(cpu->Lres1m); ++ cpu->KR = OSSwapInt64(cpu->KR); ++ cpu->KI = OSSwapInt64(cpu->KI); ++ cpu->T = OSSwapInt64(cpu->T); ++ cpu->Fsr3 = OSSwapInt32(cpu->Fsr3); ++ cpu->Fsr2 = OSSwapInt32(cpu->Fsr2); ++ cpu->Fsr1 = OSSwapInt32(cpu->Fsr1); ++ cpu->Mergelo32 = OSSwapInt32(cpu->Mergelo32); ++ cpu->Mergehi32 = OSSwapInt32(cpu->Mergehi32); + } + #endif /* !defined(RLD) */ +Index: odcctools-9.2-ld/libmacho/m68k_swap.c +=================================================================== +--- odcctools-9.2-ld.orig/libmacho/m68k_swap.c 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/libmacho/m68k_swap.c 2013-09-03 21:08:01.873209515 +0000 +@@ -28,15 +28,15 @@ + struct m68k_thread_state_regs *cpu, + enum NXByteOrder target_byte_sex) + { +- unsigned long i; ++ uint32_t i; + + for(i = 0; i < 8; i++) +- cpu->dreg[i] = NXSwapLong(cpu->dreg[i]); ++ cpu->dreg[i] = OSSwapInt32(cpu->dreg[i]); + for(i = 0; i < 8; i++) +- cpu->areg[i] = NXSwapLong(cpu->areg[i]); +- cpu->pad0 = NXSwapShort(cpu->pad0); +- cpu->sr = NXSwapShort(cpu->sr); +- cpu->pc = NXSwapLong(cpu->pc); ++ cpu->areg[i] = OSSwapInt32(cpu->areg[i]); ++ cpu->pad0 = OSSwapInt16(cpu->pad0); ++ cpu->sr = OSSwapInt16(cpu->sr); ++ cpu->pc = OSSwapInt32(cpu->pc); + } + + void +@@ -44,18 +44,18 @@ + struct m68k_thread_state_68882 *fpu, + enum NXByteOrder target_byte_sex) + { +- unsigned long i, tmp; ++ uint32_t i, tmp; + + for(i = 0; i < 8; i++){ +- tmp = NXSwapLong(fpu->regs[i].fp[0]); +- fpu->regs[i].fp[1] = NXSwapLong(fpu->regs[i].fp[1]); +- fpu->regs[i].fp[0] = NXSwapLong(fpu->regs[i].fp[2]); ++ tmp = OSSwapInt32(fpu->regs[i].fp[0]); ++ fpu->regs[i].fp[1] = OSSwapInt32(fpu->regs[i].fp[1]); ++ fpu->regs[i].fp[0] = OSSwapInt32(fpu->regs[i].fp[2]); + fpu->regs[i].fp[2] = tmp; + } +- fpu->cr = NXSwapLong(fpu->cr); +- fpu->sr = NXSwapLong(fpu->sr); +- fpu->iar = NXSwapLong(fpu->iar); +- fpu->state = NXSwapLong(fpu->state); ++ fpu->cr = OSSwapInt32(fpu->cr); ++ fpu->sr = OSSwapInt32(fpu->sr); ++ fpu->iar = OSSwapInt32(fpu->iar); ++ fpu->state = OSSwapInt32(fpu->state); + } + + void +@@ -63,6 +63,6 @@ + struct m68k_thread_state_user_reg *user_reg, + enum NXByteOrder target_byte_sex) + { +- user_reg->user_reg = NXSwapLong(user_reg->user_reg); ++ user_reg->user_reg = OSSwapInt32(user_reg->user_reg); + } + #endif /* !defined(RLD) */ +Index: odcctools-9.2-ld/libmacho/m88k_swap.c +=================================================================== +--- odcctools-9.2-ld.orig/libmacho/m88k_swap.c 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/libmacho/m88k_swap.c 2013-09-03 21:08:01.873209515 +0000 +@@ -30,40 +30,40 @@ + m88k_thread_state_grf_t *cpu, + enum NXByteOrder target_byte_sex) + { +- cpu->r1 = NXSwapLong(cpu->r1); +- cpu->r2 = NXSwapLong(cpu->r2); +- cpu->r3 = NXSwapLong(cpu->r3); +- cpu->r4 = NXSwapLong(cpu->r4); +- cpu->r5 = NXSwapLong(cpu->r5); +- cpu->r6 = NXSwapLong(cpu->r6); +- cpu->r7 = NXSwapLong(cpu->r7); +- cpu->r8 = NXSwapLong(cpu->r8); +- cpu->r9 = NXSwapLong(cpu->r9); +- cpu->r10 = NXSwapLong(cpu->r10); +- cpu->r11 = NXSwapLong(cpu->r11); +- cpu->r12 = NXSwapLong(cpu->r12); +- cpu->r13 = NXSwapLong(cpu->r13); +- cpu->r14 = NXSwapLong(cpu->r14); +- cpu->r15 = NXSwapLong(cpu->r15); +- cpu->r16 = NXSwapLong(cpu->r16); +- cpu->r17 = NXSwapLong(cpu->r17); +- cpu->r18 = NXSwapLong(cpu->r18); +- cpu->r19 = NXSwapLong(cpu->r19); +- cpu->r20 = NXSwapLong(cpu->r20); +- cpu->r21 = NXSwapLong(cpu->r21); +- cpu->r22 = NXSwapLong(cpu->r22); +- cpu->r23 = NXSwapLong(cpu->r23); +- cpu->r24 = NXSwapLong(cpu->r24); +- cpu->r25 = NXSwapLong(cpu->r25); +- cpu->r26 = NXSwapLong(cpu->r26); +- cpu->r27 = NXSwapLong(cpu->r27); +- cpu->r28 = NXSwapLong(cpu->r28); +- cpu->r29 = NXSwapLong(cpu->r29); +- cpu->r30 = NXSwapLong(cpu->r30); +- cpu->r31 = NXSwapLong(cpu->r31); +- cpu->xip = NXSwapLong(cpu->xip); +- cpu->xip_in_bd = NXSwapLong(cpu->xip_in_bd); +- cpu->nip = NXSwapLong(cpu->nip); ++ cpu->r1 = OSSwapInt32(cpu->r1); ++ cpu->r2 = OSSwapInt32(cpu->r2); ++ cpu->r3 = OSSwapInt32(cpu->r3); ++ cpu->r4 = OSSwapInt32(cpu->r4); ++ cpu->r5 = OSSwapInt32(cpu->r5); ++ cpu->r6 = OSSwapInt32(cpu->r6); ++ cpu->r7 = OSSwapInt32(cpu->r7); ++ cpu->r8 = OSSwapInt32(cpu->r8); ++ cpu->r9 = OSSwapInt32(cpu->r9); ++ cpu->r10 = OSSwapInt32(cpu->r10); ++ cpu->r11 = OSSwapInt32(cpu->r11); ++ cpu->r12 = OSSwapInt32(cpu->r12); ++ cpu->r13 = OSSwapInt32(cpu->r13); ++ cpu->r14 = OSSwapInt32(cpu->r14); ++ cpu->r15 = OSSwapInt32(cpu->r15); ++ cpu->r16 = OSSwapInt32(cpu->r16); ++ cpu->r17 = OSSwapInt32(cpu->r17); ++ cpu->r18 = OSSwapInt32(cpu->r18); ++ cpu->r19 = OSSwapInt32(cpu->r19); ++ cpu->r20 = OSSwapInt32(cpu->r20); ++ cpu->r21 = OSSwapInt32(cpu->r21); ++ cpu->r22 = OSSwapInt32(cpu->r22); ++ cpu->r23 = OSSwapInt32(cpu->r23); ++ cpu->r24 = OSSwapInt32(cpu->r24); ++ cpu->r25 = OSSwapInt32(cpu->r25); ++ cpu->r26 = OSSwapInt32(cpu->r26); ++ cpu->r27 = OSSwapInt32(cpu->r27); ++ cpu->r28 = OSSwapInt32(cpu->r28); ++ cpu->r29 = OSSwapInt32(cpu->r29); ++ cpu->r30 = OSSwapInt32(cpu->r30); ++ cpu->r31 = OSSwapInt32(cpu->r31); ++ cpu->xip = OSSwapInt32(cpu->xip); ++ cpu->xip_in_bd = OSSwapInt32(cpu->xip_in_bd); ++ cpu->nip = OSSwapInt32(cpu->nip); + } + + void +@@ -85,7 +85,7 @@ + unsigned xmod:BIT_WIDTH(16); + unsigned :BITS_WIDTH(31,17); + } fields; +- unsigned long word; ++ uint32_t word; + } u; + } ssr; + struct swapped_m88k_fpcr { +@@ -100,140 +100,140 @@ + m88k_fpcr_rm_t rm:BITS_WIDTH(15,14); + unsigned :BITS_WIDTH(31,16); + } fields; +- unsigned long word; ++ uint32_t word; + } u; + } scr; + + host_byte_sex = NXHostByteOrder(); + +- fpu->x1.x[0] = NXSwapLong(fpu->x1.x[0]); +- fpu->x1.x[1] = NXSwapLong(fpu->x1.x[1]); +- fpu->x1.x[2] = NXSwapLong(fpu->x1.x[2]); +- fpu->x1.x[3] = NXSwapLong(fpu->x1.x[3]); +- fpu->x2.x[0] = NXSwapLong(fpu->x2.x[0]); +- fpu->x2.x[1] = NXSwapLong(fpu->x2.x[1]); +- fpu->x2.x[2] = NXSwapLong(fpu->x2.x[2]); +- fpu->x2.x[3] = NXSwapLong(fpu->x2.x[3]); +- fpu->x3.x[0] = NXSwapLong(fpu->x3.x[0]); +- fpu->x3.x[1] = NXSwapLong(fpu->x3.x[1]); +- fpu->x3.x[2] = NXSwapLong(fpu->x3.x[2]); +- fpu->x3.x[3] = NXSwapLong(fpu->x3.x[3]); +- fpu->x4.x[0] = NXSwapLong(fpu->x4.x[0]); +- fpu->x4.x[1] = NXSwapLong(fpu->x4.x[1]); +- fpu->x4.x[2] = NXSwapLong(fpu->x4.x[2]); +- fpu->x4.x[3] = NXSwapLong(fpu->x4.x[3]); +- fpu->x5.x[0] = NXSwapLong(fpu->x5.x[0]); +- fpu->x5.x[1] = NXSwapLong(fpu->x5.x[1]); +- fpu->x5.x[2] = NXSwapLong(fpu->x5.x[2]); +- fpu->x5.x[3] = NXSwapLong(fpu->x5.x[3]); +- fpu->x6.x[0] = NXSwapLong(fpu->x6.x[0]); +- fpu->x6.x[1] = NXSwapLong(fpu->x6.x[1]); +- fpu->x6.x[2] = NXSwapLong(fpu->x6.x[2]); +- fpu->x6.x[3] = NXSwapLong(fpu->x6.x[3]); +- fpu->x7.x[0] = NXSwapLong(fpu->x7.x[0]); +- fpu->x7.x[1] = NXSwapLong(fpu->x7.x[1]); +- fpu->x7.x[2] = NXSwapLong(fpu->x7.x[2]); +- fpu->x7.x[3] = NXSwapLong(fpu->x7.x[3]); +- fpu->x8.x[0] = NXSwapLong(fpu->x8.x[0]); +- fpu->x8.x[1] = NXSwapLong(fpu->x8.x[1]); +- fpu->x8.x[2] = NXSwapLong(fpu->x8.x[2]); +- fpu->x8.x[3] = NXSwapLong(fpu->x8.x[3]); +- fpu->x9.x[0] = NXSwapLong(fpu->x9.x[0]); +- fpu->x9.x[1] = NXSwapLong(fpu->x9.x[1]); +- fpu->x9.x[2] = NXSwapLong(fpu->x9.x[2]); +- fpu->x9.x[3] = NXSwapLong(fpu->x9.x[3]); +- fpu->x10.x[0] = NXSwapLong(fpu->x10.x[0]); +- fpu->x10.x[1] = NXSwapLong(fpu->x10.x[1]); +- fpu->x10.x[2] = NXSwapLong(fpu->x10.x[2]); +- fpu->x10.x[3] = NXSwapLong(fpu->x10.x[3]); +- fpu->x11.x[0] = NXSwapLong(fpu->x11.x[0]); +- fpu->x11.x[1] = NXSwapLong(fpu->x11.x[1]); +- fpu->x11.x[2] = NXSwapLong(fpu->x11.x[2]); +- fpu->x11.x[3] = NXSwapLong(fpu->x11.x[3]); +- fpu->x12.x[0] = NXSwapLong(fpu->x12.x[0]); +- fpu->x12.x[1] = NXSwapLong(fpu->x12.x[1]); +- fpu->x12.x[2] = NXSwapLong(fpu->x12.x[2]); +- fpu->x12.x[3] = NXSwapLong(fpu->x12.x[3]); +- fpu->x13.x[0] = NXSwapLong(fpu->x13.x[0]); +- fpu->x13.x[1] = NXSwapLong(fpu->x13.x[1]); +- fpu->x13.x[2] = NXSwapLong(fpu->x13.x[2]); +- fpu->x13.x[3] = NXSwapLong(fpu->x13.x[3]); +- fpu->x14.x[0] = NXSwapLong(fpu->x14.x[0]); +- fpu->x14.x[1] = NXSwapLong(fpu->x14.x[1]); +- fpu->x14.x[2] = NXSwapLong(fpu->x14.x[2]); +- fpu->x14.x[3] = NXSwapLong(fpu->x14.x[3]); +- fpu->x15.x[0] = NXSwapLong(fpu->x15.x[0]); +- fpu->x15.x[1] = NXSwapLong(fpu->x15.x[1]); +- fpu->x15.x[2] = NXSwapLong(fpu->x15.x[2]); +- fpu->x15.x[3] = NXSwapLong(fpu->x15.x[3]); +- fpu->x16.x[0] = NXSwapLong(fpu->x16.x[0]); +- fpu->x16.x[1] = NXSwapLong(fpu->x16.x[1]); +- fpu->x16.x[2] = NXSwapLong(fpu->x16.x[2]); +- fpu->x16.x[3] = NXSwapLong(fpu->x16.x[3]); +- fpu->x17.x[0] = NXSwapLong(fpu->x17.x[0]); +- fpu->x17.x[1] = NXSwapLong(fpu->x17.x[1]); +- fpu->x17.x[2] = NXSwapLong(fpu->x17.x[2]); +- fpu->x17.x[3] = NXSwapLong(fpu->x17.x[3]); +- fpu->x18.x[0] = NXSwapLong(fpu->x18.x[0]); +- fpu->x18.x[1] = NXSwapLong(fpu->x18.x[1]); +- fpu->x18.x[2] = NXSwapLong(fpu->x18.x[2]); +- fpu->x18.x[3] = NXSwapLong(fpu->x18.x[3]); +- fpu->x19.x[0] = NXSwapLong(fpu->x19.x[0]); +- fpu->x19.x[1] = NXSwapLong(fpu->x19.x[1]); +- fpu->x19.x[2] = NXSwapLong(fpu->x19.x[2]); +- fpu->x19.x[3] = NXSwapLong(fpu->x19.x[3]); +- fpu->x20.x[0] = NXSwapLong(fpu->x20.x[0]); +- fpu->x20.x[1] = NXSwapLong(fpu->x20.x[1]); +- fpu->x20.x[2] = NXSwapLong(fpu->x20.x[2]); +- fpu->x20.x[3] = NXSwapLong(fpu->x20.x[3]); +- fpu->x21.x[0] = NXSwapLong(fpu->x21.x[0]); +- fpu->x21.x[1] = NXSwapLong(fpu->x21.x[1]); +- fpu->x21.x[2] = NXSwapLong(fpu->x21.x[2]); +- fpu->x21.x[3] = NXSwapLong(fpu->x21.x[3]); +- fpu->x22.x[0] = NXSwapLong(fpu->x22.x[0]); +- fpu->x22.x[1] = NXSwapLong(fpu->x22.x[1]); +- fpu->x22.x[2] = NXSwapLong(fpu->x22.x[2]); +- fpu->x22.x[3] = NXSwapLong(fpu->x22.x[3]); +- fpu->x23.x[0] = NXSwapLong(fpu->x23.x[0]); +- fpu->x23.x[1] = NXSwapLong(fpu->x23.x[1]); +- fpu->x23.x[2] = NXSwapLong(fpu->x23.x[2]); +- fpu->x23.x[3] = NXSwapLong(fpu->x23.x[3]); +- fpu->x24.x[0] = NXSwapLong(fpu->x24.x[0]); +- fpu->x24.x[1] = NXSwapLong(fpu->x24.x[1]); +- fpu->x24.x[2] = NXSwapLong(fpu->x24.x[2]); +- fpu->x24.x[3] = NXSwapLong(fpu->x24.x[3]); +- fpu->x25.x[0] = NXSwapLong(fpu->x25.x[0]); +- fpu->x25.x[1] = NXSwapLong(fpu->x25.x[1]); +- fpu->x25.x[2] = NXSwapLong(fpu->x25.x[2]); +- fpu->x25.x[3] = NXSwapLong(fpu->x25.x[3]); +- fpu->x26.x[0] = NXSwapLong(fpu->x26.x[0]); +- fpu->x26.x[1] = NXSwapLong(fpu->x26.x[1]); +- fpu->x26.x[2] = NXSwapLong(fpu->x26.x[2]); +- fpu->x26.x[3] = NXSwapLong(fpu->x26.x[3]); +- fpu->x27.x[0] = NXSwapLong(fpu->x27.x[0]); +- fpu->x27.x[1] = NXSwapLong(fpu->x27.x[1]); +- fpu->x27.x[2] = NXSwapLong(fpu->x27.x[2]); +- fpu->x27.x[3] = NXSwapLong(fpu->x27.x[3]); +- fpu->x28.x[0] = NXSwapLong(fpu->x28.x[0]); +- fpu->x28.x[1] = NXSwapLong(fpu->x28.x[1]); +- fpu->x28.x[2] = NXSwapLong(fpu->x28.x[2]); +- fpu->x28.x[3] = NXSwapLong(fpu->x28.x[3]); +- fpu->x29.x[0] = NXSwapLong(fpu->x29.x[0]); +- fpu->x29.x[1] = NXSwapLong(fpu->x29.x[1]); +- fpu->x29.x[2] = NXSwapLong(fpu->x29.x[2]); +- fpu->x29.x[3] = NXSwapLong(fpu->x29.x[3]); +- fpu->x30.x[0] = NXSwapLong(fpu->x30.x[0]); +- fpu->x30.x[1] = NXSwapLong(fpu->x30.x[1]); +- fpu->x30.x[2] = NXSwapLong(fpu->x30.x[2]); +- fpu->x30.x[3] = NXSwapLong(fpu->x30.x[3]); +- fpu->x31.x[0] = NXSwapLong(fpu->x31.x[0]); +- fpu->x31.x[1] = NXSwapLong(fpu->x31.x[1]); +- fpu->x31.x[2] = NXSwapLong(fpu->x31.x[2]); +- fpu->x31.x[3] = NXSwapLong(fpu->x31.x[3]); ++ fpu->x1.x[0] = OSSwapInt32(fpu->x1.x[0]); ++ fpu->x1.x[1] = OSSwapInt32(fpu->x1.x[1]); ++ fpu->x1.x[2] = OSSwapInt32(fpu->x1.x[2]); ++ fpu->x1.x[3] = OSSwapInt32(fpu->x1.x[3]); ++ fpu->x2.x[0] = OSSwapInt32(fpu->x2.x[0]); ++ fpu->x2.x[1] = OSSwapInt32(fpu->x2.x[1]); ++ fpu->x2.x[2] = OSSwapInt32(fpu->x2.x[2]); ++ fpu->x2.x[3] = OSSwapInt32(fpu->x2.x[3]); ++ fpu->x3.x[0] = OSSwapInt32(fpu->x3.x[0]); ++ fpu->x3.x[1] = OSSwapInt32(fpu->x3.x[1]); ++ fpu->x3.x[2] = OSSwapInt32(fpu->x3.x[2]); ++ fpu->x3.x[3] = OSSwapInt32(fpu->x3.x[3]); ++ fpu->x4.x[0] = OSSwapInt32(fpu->x4.x[0]); ++ fpu->x4.x[1] = OSSwapInt32(fpu->x4.x[1]); ++ fpu->x4.x[2] = OSSwapInt32(fpu->x4.x[2]); ++ fpu->x4.x[3] = OSSwapInt32(fpu->x4.x[3]); ++ fpu->x5.x[0] = OSSwapInt32(fpu->x5.x[0]); ++ fpu->x5.x[1] = OSSwapInt32(fpu->x5.x[1]); ++ fpu->x5.x[2] = OSSwapInt32(fpu->x5.x[2]); ++ fpu->x5.x[3] = OSSwapInt32(fpu->x5.x[3]); ++ fpu->x6.x[0] = OSSwapInt32(fpu->x6.x[0]); ++ fpu->x6.x[1] = OSSwapInt32(fpu->x6.x[1]); ++ fpu->x6.x[2] = OSSwapInt32(fpu->x6.x[2]); ++ fpu->x6.x[3] = OSSwapInt32(fpu->x6.x[3]); ++ fpu->x7.x[0] = OSSwapInt32(fpu->x7.x[0]); ++ fpu->x7.x[1] = OSSwapInt32(fpu->x7.x[1]); ++ fpu->x7.x[2] = OSSwapInt32(fpu->x7.x[2]); ++ fpu->x7.x[3] = OSSwapInt32(fpu->x7.x[3]); ++ fpu->x8.x[0] = OSSwapInt32(fpu->x8.x[0]); ++ fpu->x8.x[1] = OSSwapInt32(fpu->x8.x[1]); ++ fpu->x8.x[2] = OSSwapInt32(fpu->x8.x[2]); ++ fpu->x8.x[3] = OSSwapInt32(fpu->x8.x[3]); ++ fpu->x9.x[0] = OSSwapInt32(fpu->x9.x[0]); ++ fpu->x9.x[1] = OSSwapInt32(fpu->x9.x[1]); ++ fpu->x9.x[2] = OSSwapInt32(fpu->x9.x[2]); ++ fpu->x9.x[3] = OSSwapInt32(fpu->x9.x[3]); ++ fpu->x10.x[0] = OSSwapInt32(fpu->x10.x[0]); ++ fpu->x10.x[1] = OSSwapInt32(fpu->x10.x[1]); ++ fpu->x10.x[2] = OSSwapInt32(fpu->x10.x[2]); ++ fpu->x10.x[3] = OSSwapInt32(fpu->x10.x[3]); ++ fpu->x11.x[0] = OSSwapInt32(fpu->x11.x[0]); ++ fpu->x11.x[1] = OSSwapInt32(fpu->x11.x[1]); ++ fpu->x11.x[2] = OSSwapInt32(fpu->x11.x[2]); ++ fpu->x11.x[3] = OSSwapInt32(fpu->x11.x[3]); ++ fpu->x12.x[0] = OSSwapInt32(fpu->x12.x[0]); ++ fpu->x12.x[1] = OSSwapInt32(fpu->x12.x[1]); ++ fpu->x12.x[2] = OSSwapInt32(fpu->x12.x[2]); ++ fpu->x12.x[3] = OSSwapInt32(fpu->x12.x[3]); ++ fpu->x13.x[0] = OSSwapInt32(fpu->x13.x[0]); ++ fpu->x13.x[1] = OSSwapInt32(fpu->x13.x[1]); ++ fpu->x13.x[2] = OSSwapInt32(fpu->x13.x[2]); ++ fpu->x13.x[3] = OSSwapInt32(fpu->x13.x[3]); ++ fpu->x14.x[0] = OSSwapInt32(fpu->x14.x[0]); ++ fpu->x14.x[1] = OSSwapInt32(fpu->x14.x[1]); ++ fpu->x14.x[2] = OSSwapInt32(fpu->x14.x[2]); ++ fpu->x14.x[3] = OSSwapInt32(fpu->x14.x[3]); ++ fpu->x15.x[0] = OSSwapInt32(fpu->x15.x[0]); ++ fpu->x15.x[1] = OSSwapInt32(fpu->x15.x[1]); ++ fpu->x15.x[2] = OSSwapInt32(fpu->x15.x[2]); ++ fpu->x15.x[3] = OSSwapInt32(fpu->x15.x[3]); ++ fpu->x16.x[0] = OSSwapInt32(fpu->x16.x[0]); ++ fpu->x16.x[1] = OSSwapInt32(fpu->x16.x[1]); ++ fpu->x16.x[2] = OSSwapInt32(fpu->x16.x[2]); ++ fpu->x16.x[3] = OSSwapInt32(fpu->x16.x[3]); ++ fpu->x17.x[0] = OSSwapInt32(fpu->x17.x[0]); ++ fpu->x17.x[1] = OSSwapInt32(fpu->x17.x[1]); ++ fpu->x17.x[2] = OSSwapInt32(fpu->x17.x[2]); ++ fpu->x17.x[3] = OSSwapInt32(fpu->x17.x[3]); ++ fpu->x18.x[0] = OSSwapInt32(fpu->x18.x[0]); ++ fpu->x18.x[1] = OSSwapInt32(fpu->x18.x[1]); ++ fpu->x18.x[2] = OSSwapInt32(fpu->x18.x[2]); ++ fpu->x18.x[3] = OSSwapInt32(fpu->x18.x[3]); ++ fpu->x19.x[0] = OSSwapInt32(fpu->x19.x[0]); ++ fpu->x19.x[1] = OSSwapInt32(fpu->x19.x[1]); ++ fpu->x19.x[2] = OSSwapInt32(fpu->x19.x[2]); ++ fpu->x19.x[3] = OSSwapInt32(fpu->x19.x[3]); ++ fpu->x20.x[0] = OSSwapInt32(fpu->x20.x[0]); ++ fpu->x20.x[1] = OSSwapInt32(fpu->x20.x[1]); ++ fpu->x20.x[2] = OSSwapInt32(fpu->x20.x[2]); ++ fpu->x20.x[3] = OSSwapInt32(fpu->x20.x[3]); ++ fpu->x21.x[0] = OSSwapInt32(fpu->x21.x[0]); ++ fpu->x21.x[1] = OSSwapInt32(fpu->x21.x[1]); ++ fpu->x21.x[2] = OSSwapInt32(fpu->x21.x[2]); ++ fpu->x21.x[3] = OSSwapInt32(fpu->x21.x[3]); ++ fpu->x22.x[0] = OSSwapInt32(fpu->x22.x[0]); ++ fpu->x22.x[1] = OSSwapInt32(fpu->x22.x[1]); ++ fpu->x22.x[2] = OSSwapInt32(fpu->x22.x[2]); ++ fpu->x22.x[3] = OSSwapInt32(fpu->x22.x[3]); ++ fpu->x23.x[0] = OSSwapInt32(fpu->x23.x[0]); ++ fpu->x23.x[1] = OSSwapInt32(fpu->x23.x[1]); ++ fpu->x23.x[2] = OSSwapInt32(fpu->x23.x[2]); ++ fpu->x23.x[3] = OSSwapInt32(fpu->x23.x[3]); ++ fpu->x24.x[0] = OSSwapInt32(fpu->x24.x[0]); ++ fpu->x24.x[1] = OSSwapInt32(fpu->x24.x[1]); ++ fpu->x24.x[2] = OSSwapInt32(fpu->x24.x[2]); ++ fpu->x24.x[3] = OSSwapInt32(fpu->x24.x[3]); ++ fpu->x25.x[0] = OSSwapInt32(fpu->x25.x[0]); ++ fpu->x25.x[1] = OSSwapInt32(fpu->x25.x[1]); ++ fpu->x25.x[2] = OSSwapInt32(fpu->x25.x[2]); ++ fpu->x25.x[3] = OSSwapInt32(fpu->x25.x[3]); ++ fpu->x26.x[0] = OSSwapInt32(fpu->x26.x[0]); ++ fpu->x26.x[1] = OSSwapInt32(fpu->x26.x[1]); ++ fpu->x26.x[2] = OSSwapInt32(fpu->x26.x[2]); ++ fpu->x26.x[3] = OSSwapInt32(fpu->x26.x[3]); ++ fpu->x27.x[0] = OSSwapInt32(fpu->x27.x[0]); ++ fpu->x27.x[1] = OSSwapInt32(fpu->x27.x[1]); ++ fpu->x27.x[2] = OSSwapInt32(fpu->x27.x[2]); ++ fpu->x27.x[3] = OSSwapInt32(fpu->x27.x[3]); ++ fpu->x28.x[0] = OSSwapInt32(fpu->x28.x[0]); ++ fpu->x28.x[1] = OSSwapInt32(fpu->x28.x[1]); ++ fpu->x28.x[2] = OSSwapInt32(fpu->x28.x[2]); ++ fpu->x28.x[3] = OSSwapInt32(fpu->x28.x[3]); ++ fpu->x29.x[0] = OSSwapInt32(fpu->x29.x[0]); ++ fpu->x29.x[1] = OSSwapInt32(fpu->x29.x[1]); ++ fpu->x29.x[2] = OSSwapInt32(fpu->x29.x[2]); ++ fpu->x29.x[3] = OSSwapInt32(fpu->x29.x[3]); ++ fpu->x30.x[0] = OSSwapInt32(fpu->x30.x[0]); ++ fpu->x30.x[1] = OSSwapInt32(fpu->x30.x[1]); ++ fpu->x30.x[2] = OSSwapInt32(fpu->x30.x[2]); ++ fpu->x30.x[3] = OSSwapInt32(fpu->x30.x[3]); ++ fpu->x31.x[0] = OSSwapInt32(fpu->x31.x[0]); ++ fpu->x31.x[1] = OSSwapInt32(fpu->x31.x[1]); ++ fpu->x31.x[2] = OSSwapInt32(fpu->x31.x[2]); ++ fpu->x31.x[3] = OSSwapInt32(fpu->x31.x[3]); + + if(target_byte_sex == host_byte_sex){ + memcpy(&ssr, &(fpu->fpsr), sizeof(struct swapped_m88k_fpsr)); +- ssr.u.word = NXSwapLong(ssr.u.word); ++ ssr.u.word = OSSwapInt32(ssr.u.word); + fpu->fpsr.afinx = ssr.u.fields.afinx; + fpu->fpsr.afovf = ssr.u.fields.afovf; + fpu->fpsr.afunf = ssr.u.fields.afunf; +@@ -242,7 +242,7 @@ + fpu->fpsr.xmod = ssr.u.fields.xmod; + + memcpy(&scr, &(fpu->fpcr), sizeof(struct swapped_m88k_fpcr)); +- scr.u.word = NXSwapLong(scr.u.word); ++ scr.u.word = OSSwapInt32(scr.u.word); + fpu->fpcr.efinx = scr.u.fields.efinx; + fpu->fpcr.efovf = scr.u.fields.efovf; + fpu->fpcr.efunf = scr.u.fields.efunf; +@@ -257,7 +257,7 @@ + ssr.u.fields.afdvz = fpu->fpsr.afdvz; + ssr.u.fields.afinv = fpu->fpsr.afinv; + ssr.u.fields.xmod = fpu->fpsr.xmod; +- ssr.u.word = NXSwapLong(ssr.u.word); ++ ssr.u.word = OSSwapInt32(ssr.u.word); + memcpy(&(fpu->fpsr), &ssr, sizeof(struct swapped_m88k_fpsr)); + + scr.u.fields.efinx = fpu->fpcr.efinx; +@@ -266,7 +266,7 @@ + scr.u.fields.efdvz = fpu->fpcr.efdvz; + scr.u.fields.efinv = fpu->fpcr.efinv; + scr.u.fields.rm = fpu->fpcr.rm; +- scr.u.word = NXSwapLong(scr.u.word); ++ scr.u.word = OSSwapInt32(scr.u.word); + memcpy(&(fpu->fpcr), &scr, sizeof(struct swapped_m88k_fpcr)); + } + } +@@ -276,7 +276,7 @@ + m88k_thread_state_user_t *user, + enum NXByteOrder target_byte_sex) + { +- user->user = NXSwapLong(user->user); ++ user->user = OSSwapInt32(user->user); + } + + void +@@ -284,7 +284,7 @@ + m88110_thread_state_impl_t *spu, + enum NXByteOrder target_byte_sex) + { +- unsigned long i; ++ uint32_t i; + enum NXByteOrder host_byte_sex; + + struct swapped_m88110_bp_ctrl { +@@ -297,7 +297,7 @@ + unsigned rw:BIT_WIDTH(28); + unsigned :BITS_WIDTH(31,29); + } fields; +- unsigned long word; ++ uint32_t word; + } u; + } sbpc; + +@@ -318,7 +318,7 @@ + unsigned le:BIT_WIDTH(30); + unsigned supr:BIT_WIDTH(31); + } fields; +- unsigned long word; ++ uint32_t word; + } u; + } spsr; + +@@ -338,7 +338,7 @@ + m88110_iresult_size_t iresult_size:BITS_WIDTH(15,14); + unsigned :BITS_WIDTH(31,16); + } fields; +- unsigned long word; ++ uint32_t word; + } u; + } sfps; + +@@ -346,10 +346,10 @@ + + if(target_byte_sex == host_byte_sex){ + for(i = 0; i < M88110_N_DATA_BP; i++){ +- spu->data_bp[i].addr = NXSwapLong(spu->data_bp[i].addr); ++ spu->data_bp[i].addr = OSSwapInt32(spu->data_bp[i].addr); + memcpy(&sbpc, &(spu->data_bp[i].ctrl), + sizeof(struct swapped_m88110_bp_ctrl)); +- sbpc.u.word = NXSwapLong(sbpc.u.word); ++ sbpc.u.word = OSSwapInt32(sbpc.u.word); + spu->data_bp[i].ctrl.v = sbpc.u.fields.v; + spu->data_bp[i].ctrl.addr_match = sbpc.u.fields.addr_match; + spu->data_bp[i].ctrl.rwm = sbpc.u.fields.rwm; +@@ -357,7 +357,7 @@ + } + + memcpy(&spsr, &(spu->psr), sizeof(struct swap_m88110_psr)); +- spsr.u.word = NXSwapLong(spsr.u.word); ++ spsr.u.word = OSSwapInt32(spsr.u.word); + spu->psr.mxm_dis = spsr.u.fields.mxm_dis; + spu->psr.sfu1dis = spsr.u.fields.sfu1dis; + spu->psr.trace = spsr.u.fields.trace; +@@ -370,7 +370,7 @@ + + memcpy(&sfps, &(spu->fp_trap_status), + sizeof(struct swapped_m88110_fp_trap_status)); +- sfps.u.word = NXSwapLong(sfps.u.word); ++ sfps.u.word = OSSwapInt32(sfps.u.word); + spu->fp_trap_status.efinx = sfps.u.fields.efinx; + spu->fp_trap_status.efovf = sfps.u.fields.efovf; + spu->fp_trap_status.efunf = sfps.u.fields.efunf; +@@ -383,12 +383,12 @@ + } + else{ + for(i = 0; i < M88110_N_DATA_BP; i++){ +- spu->data_bp[i].addr = NXSwapLong(spu->data_bp[i].addr); ++ spu->data_bp[i].addr = OSSwapInt32(spu->data_bp[i].addr); + sbpc.u.fields.v = spu->data_bp[i].ctrl.v; + sbpc.u.fields.addr_match = spu->data_bp[i].ctrl.addr_match; + sbpc.u.fields.rwm = spu->data_bp[i].ctrl.rwm; + sbpc.u.fields.rw = spu->data_bp[i].ctrl.rw; +- sbpc.u.word = NXSwapLong(sbpc.u.word); ++ sbpc.u.word = OSSwapInt32(sbpc.u.word); + memcpy(&(spu->data_bp[i].ctrl), &sbpc, + sizeof(struct swapped_m88110_bp_ctrl)); + } +@@ -402,7 +402,7 @@ + spsr.u.fields.se = spu->psr.se; + spsr.u.fields.le = spu->psr.le; + spsr.u.fields.supr = spu->psr.supr; +- spsr.u.word = NXSwapLong(spsr.u.word); ++ spsr.u.word = OSSwapInt32(spsr.u.word); + memcpy(&(spu->psr), &spsr, sizeof(struct swap_m88110_psr)); + + sfps.u.fields.efinx = spu->fp_trap_status.efinx; +@@ -414,17 +414,17 @@ + sfps.u.fields.unimp = spu->fp_trap_status.unimp; + sfps.u.fields.sfu1_disabled = spu->fp_trap_status.sfu1_disabled; + sfps.u.fields.iresult_size = spu->fp_trap_status.iresult_size; +- sfps.u.word = NXSwapLong(sfps.u.word); ++ sfps.u.word = OSSwapInt32(sfps.u.word); + memcpy(&(spu->fp_trap_status), &sfps, + sizeof(struct swapped_m88110_fp_trap_status)); + } + spu->intermediate_result.x[0] = +- NXSwapLong(spu->intermediate_result.x[0]); ++ OSSwapInt32(spu->intermediate_result.x[0]); + spu->intermediate_result.x[1] = +- NXSwapLong(spu->intermediate_result.x[1]); ++ OSSwapInt32(spu->intermediate_result.x[1]); + spu->intermediate_result.x[2] = +- NXSwapLong(spu->intermediate_result.x[2]); ++ OSSwapInt32(spu->intermediate_result.x[2]); + spu->intermediate_result.x[3] = +- NXSwapLong(spu->intermediate_result.x[3]); ++ OSSwapInt32(spu->intermediate_result.x[3]); + } + #endif /* !defined(RLD) */ +Index: odcctools-9.2-ld/libmacho/ppc_swap.c +=================================================================== +--- odcctools-9.2-ld.orig/libmacho/ppc_swap.c 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/libmacho/ppc_swap.c 2013-09-03 21:08:01.873209515 +0000 +@@ -79,46 +79,46 @@ + ppc_thread_state_t *cpu, + enum NXByteOrder target_byte_sex) + { +- cpu->srr0 = NXSwapLong(cpu->srr0); +- cpu->srr1 = NXSwapLong(cpu->srr1); +- cpu->r0 = NXSwapLong(cpu->r0); +- cpu->r1 = NXSwapLong(cpu->r1); +- cpu->r2 = NXSwapLong(cpu->r2); +- cpu->r3 = NXSwapLong(cpu->r3); +- cpu->r4 = NXSwapLong(cpu->r4); +- cpu->r5 = NXSwapLong(cpu->r5); +- cpu->r6 = NXSwapLong(cpu->r6); +- cpu->r7 = NXSwapLong(cpu->r7); +- cpu->r8 = NXSwapLong(cpu->r8); +- cpu->r9 = NXSwapLong(cpu->r9); +- cpu->r10 = NXSwapLong(cpu->r10); +- cpu->r11 = NXSwapLong(cpu->r11); +- cpu->r12 = NXSwapLong(cpu->r12); +- cpu->r13 = NXSwapLong(cpu->r13); +- cpu->r14 = NXSwapLong(cpu->r14); +- cpu->r15 = NXSwapLong(cpu->r15); +- cpu->r16 = NXSwapLong(cpu->r16); +- cpu->r17 = NXSwapLong(cpu->r17); +- cpu->r18 = NXSwapLong(cpu->r18); +- cpu->r19 = NXSwapLong(cpu->r19); +- cpu->r20 = NXSwapLong(cpu->r20); +- cpu->r21 = NXSwapLong(cpu->r21); +- cpu->r22 = NXSwapLong(cpu->r22); +- cpu->r23 = NXSwapLong(cpu->r23); +- cpu->r24 = NXSwapLong(cpu->r24); +- cpu->r25 = NXSwapLong(cpu->r25); +- cpu->r26 = NXSwapLong(cpu->r26); +- cpu->r27 = NXSwapLong(cpu->r27); +- cpu->r28 = NXSwapLong(cpu->r28); +- cpu->r29 = NXSwapLong(cpu->r29); +- cpu->r30 = NXSwapLong(cpu->r30); +- cpu->r31 = NXSwapLong(cpu->r31); +- cpu->lr = NXSwapLong(cpu->lr); +- cpu->cr = NXSwapLong(cpu->cr); +- cpu->xer = NXSwapLong(cpu->xer); +- cpu->ctr = NXSwapLong(cpu->ctr); +- cpu->mq = NXSwapLong(cpu->mq); +- cpu->vrsave = NXSwapLong(cpu->vrsave); ++ cpu->srr0 = OSSwapInt32(cpu->srr0); ++ cpu->srr1 = OSSwapInt32(cpu->srr1); ++ cpu->r0 = OSSwapInt32(cpu->r0); ++ cpu->r1 = OSSwapInt32(cpu->r1); ++ cpu->r2 = OSSwapInt32(cpu->r2); ++ cpu->r3 = OSSwapInt32(cpu->r3); ++ cpu->r4 = OSSwapInt32(cpu->r4); ++ cpu->r5 = OSSwapInt32(cpu->r5); ++ cpu->r6 = OSSwapInt32(cpu->r6); ++ cpu->r7 = OSSwapInt32(cpu->r7); ++ cpu->r8 = OSSwapInt32(cpu->r8); ++ cpu->r9 = OSSwapInt32(cpu->r9); ++ cpu->r10 = OSSwapInt32(cpu->r10); ++ cpu->r11 = OSSwapInt32(cpu->r11); ++ cpu->r12 = OSSwapInt32(cpu->r12); ++ cpu->r13 = OSSwapInt32(cpu->r13); ++ cpu->r14 = OSSwapInt32(cpu->r14); ++ cpu->r15 = OSSwapInt32(cpu->r15); ++ cpu->r16 = OSSwapInt32(cpu->r16); ++ cpu->r17 = OSSwapInt32(cpu->r17); ++ cpu->r18 = OSSwapInt32(cpu->r18); ++ cpu->r19 = OSSwapInt32(cpu->r19); ++ cpu->r20 = OSSwapInt32(cpu->r20); ++ cpu->r21 = OSSwapInt32(cpu->r21); ++ cpu->r22 = OSSwapInt32(cpu->r22); ++ cpu->r23 = OSSwapInt32(cpu->r23); ++ cpu->r24 = OSSwapInt32(cpu->r24); ++ cpu->r25 = OSSwapInt32(cpu->r25); ++ cpu->r26 = OSSwapInt32(cpu->r26); ++ cpu->r27 = OSSwapInt32(cpu->r27); ++ cpu->r28 = OSSwapInt32(cpu->r28); ++ cpu->r29 = OSSwapInt32(cpu->r29); ++ cpu->r30 = OSSwapInt32(cpu->r30); ++ cpu->r31 = OSSwapInt32(cpu->r31); ++ cpu->lr = OSSwapInt32(cpu->lr); ++ cpu->cr = OSSwapInt32(cpu->cr); ++ cpu->xer = OSSwapInt32(cpu->xer); ++ cpu->ctr = OSSwapInt32(cpu->ctr); ++ cpu->mq = OSSwapInt32(cpu->mq); ++ cpu->vrsave = OSSwapInt32(cpu->vrsave); + + } + +@@ -127,13 +127,13 @@ + ppc_float_state_t *fpu, + enum NXByteOrder target_byte_sex) + { +- unsigned long i; ++ uint32_t i; + + for(i = 0; i < 32; i++) +- fpu->fpregs[i] = NXSwapDouble(fpu->fpregs[i]); ++ fpu->fpregs[i] = OSSwapInt64(fpu->fpregs[i]); + +- fpu->fpscr_pad = NXSwapLong(fpu->fpscr_pad); +- fpu->fpscr = NXSwapLong(fpu->fpscr); ++ fpu->fpscr_pad = OSSwapInt32(fpu->fpscr_pad); ++ fpu->fpscr = OSSwapInt32(fpu->fpscr); + } + + void +@@ -141,14 +141,14 @@ + ppc_exception_state_t *state, + enum NXByteOrder target_byte_sex) + { +- unsigned long i; ++ uint32_t i; + +- state->dar = NXSwapLong(state->dar); +- state->dsisr = NXSwapLong(state->dsisr); +- state->exception = NXSwapLong(state->exception); +- state->pad0 = NXSwapLong(state->pad0); ++ state->dar = OSSwapInt32(state->dar); ++ state->dsisr = OSSwapInt32(state->dsisr); ++ state->exception = OSSwapInt32(state->exception); ++ state->pad0 = OSSwapInt32(state->pad0); + + for(i = 0; i < 4; i++) +- state->pad1[i] = NXSwapLong(state->pad1[i]); ++ state->pad1[i] = OSSwapInt32(state->pad1[i]); + } + #endif /* !defined(RLD) */ +Index: odcctools-9.2-ld/libmacho/sparc_swap.c +=================================================================== +--- odcctools-9.2-ld.orig/libmacho/sparc_swap.c 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/libmacho/sparc_swap.c 2013-09-03 21:08:01.873209515 +0000 +@@ -54,29 +54,29 @@ + + host_byte_sex = NXHostByteOrder(); + +- cpu->regs.r_pc = NXSwapLong(cpu->regs.r_pc); +- cpu->regs.r_npc = NXSwapLong(cpu->regs.r_npc); +- cpu->regs.r_y = NXSwapLong(cpu->regs.r_y); +- cpu->regs.r_g1 = NXSwapLong(cpu->regs.r_g1); +- cpu->regs.r_g2 = NXSwapLong(cpu->regs.r_g2); +- cpu->regs.r_g3 = NXSwapLong(cpu->regs.r_g3); +- cpu->regs.r_g4 = NXSwapLong(cpu->regs.r_g4); +- cpu->regs.r_g5 = NXSwapLong(cpu->regs.r_g5); +- cpu->regs.r_g6 = NXSwapLong(cpu->regs.r_g6); +- cpu->regs.r_g7 = NXSwapLong(cpu->regs.r_g7); +- cpu->regs.r_o0 = NXSwapLong(cpu->regs.r_o0); +- cpu->regs.r_o1 = NXSwapLong(cpu->regs.r_o1); +- cpu->regs.r_o2 = NXSwapLong(cpu->regs.r_o2); +- cpu->regs.r_o3 = NXSwapLong(cpu->regs.r_o3); +- cpu->regs.r_o4 = NXSwapLong(cpu->regs.r_o4); +- cpu->regs.r_o5 = NXSwapLong(cpu->regs.r_o5); +- cpu->regs.r_o6 = NXSwapLong(cpu->regs.r_o6); +- cpu->regs.r_o7 = NXSwapLong(cpu->regs.r_o7); ++ cpu->regs.r_pc = OSSwapInt32(cpu->regs.r_pc); ++ cpu->regs.r_npc = OSSwapInt32(cpu->regs.r_npc); ++ cpu->regs.r_y = OSSwapInt32(cpu->regs.r_y); ++ cpu->regs.r_g1 = OSSwapInt32(cpu->regs.r_g1); ++ cpu->regs.r_g2 = OSSwapInt32(cpu->regs.r_g2); ++ cpu->regs.r_g3 = OSSwapInt32(cpu->regs.r_g3); ++ cpu->regs.r_g4 = OSSwapInt32(cpu->regs.r_g4); ++ cpu->regs.r_g5 = OSSwapInt32(cpu->regs.r_g5); ++ cpu->regs.r_g6 = OSSwapInt32(cpu->regs.r_g6); ++ cpu->regs.r_g7 = OSSwapInt32(cpu->regs.r_g7); ++ cpu->regs.r_o0 = OSSwapInt32(cpu->regs.r_o0); ++ cpu->regs.r_o1 = OSSwapInt32(cpu->regs.r_o1); ++ cpu->regs.r_o2 = OSSwapInt32(cpu->regs.r_o2); ++ cpu->regs.r_o3 = OSSwapInt32(cpu->regs.r_o3); ++ cpu->regs.r_o4 = OSSwapInt32(cpu->regs.r_o4); ++ cpu->regs.r_o5 = OSSwapInt32(cpu->regs.r_o5); ++ cpu->regs.r_o6 = OSSwapInt32(cpu->regs.r_o6); ++ cpu->regs.r_o7 = OSSwapInt32(cpu->regs.r_o7); + + pr_status = (struct p_status *) &(cpu->regs.r_psr); + if(target_byte_sex == host_byte_sex){ + memcpy(&spsr, &(cpu->regs.r_psr), sizeof(struct swapped_psr)); +- spsr.u.word = NXSwapLong(spsr.u.word); ++ spsr.u.word = OSSwapInt32(spsr.u.word); + pr_status->PSRREG.psr_bits.cwp = spsr.u.fields.cwp; + pr_status->PSRREG.psr_bits.ps = spsr.u.fields.ps; + pr_status->PSRREG.psr_bits.s = spsr.u.fields.s; +@@ -99,7 +99,7 @@ + spsr.u.fields.icc = pr_status->PSRREG.psr_bits.icc; + spsr.u.fields.ver = pr_status->PSRREG.psr_bits.et; + spsr.u.fields.impl = pr_status->PSRREG.psr_bits.impl; +- spsr.u.word = NXSwapLong(spsr.u.word); ++ spsr.u.word = OSSwapInt32(spsr.u.word); + memcpy(&(cpu->regs.r_psr), &spsr, sizeof(struct swapped_psr)); + } + } +@@ -127,7 +127,7 @@ + unsigned int word; + } u; + } sfsr; +- unsigned long i; ++ uint32_t i; + struct f_status *fpu_status; + enum NXByteOrder host_byte_sex; + +@@ -137,18 +137,18 @@ + /* floating point registers */ + for(i = 0; i < 16; i++) /* 16 doubles */ + fpu->fpu.fpu_fr.Fpu_dregs[i] = +- NXSwapDouble(fpu->fpu.fpu_fr.Fpu_dregs[i]); ++ OSSwapInt64(fpu->fpu.fpu_fr.Fpu_dregs[i]); + +- fpu->fpu.Fpu_q[0].FQu.whole = NXSwapDouble(fpu->fpu.Fpu_q[0].FQu.whole); +- fpu->fpu.Fpu_q[1].FQu.whole = NXSwapDouble(fpu->fpu.Fpu_q[1].FQu.whole); +- fpu->fpu.Fpu_flags = NXSwapLong(fpu->fpu.Fpu_flags); +- fpu->fpu.Fpu_extra = NXSwapLong(fpu->fpu.Fpu_extra); +- fpu->fpu.Fpu_qcnt = NXSwapLong(fpu->fpu.Fpu_qcnt); ++ fpu->fpu.Fpu_q[0].FQu.whole = OSSwapInt64(fpu->fpu.Fpu_q[0].FQu.whole); ++ fpu->fpu.Fpu_q[1].FQu.whole = OSSwapInt64(fpu->fpu.Fpu_q[1].FQu.whole); ++ fpu->fpu.Fpu_flags = OSSwapInt32(fpu->fpu.Fpu_flags); ++ fpu->fpu.Fpu_extra = OSSwapInt32(fpu->fpu.Fpu_extra); ++ fpu->fpu.Fpu_qcnt = OSSwapInt32(fpu->fpu.Fpu_qcnt); + + fpu_status = (struct f_status *) &(fpu->fpu.Fpu_fsr); + if(target_byte_sex == host_byte_sex){ + memcpy(&sfsr, &(fpu->fpu.Fpu_fsr), sizeof(unsigned int)); +- sfsr.u.word = NXSwapLong(sfsr.u.word); ++ sfsr.u.word = OSSwapInt32(sfsr.u.word); + fpu_status->FPUREG.Fpu_fsr_bits.rd = sfsr.u.fields.rd; + fpu_status->FPUREG.Fpu_fsr_bits.rp = sfsr.u.fields.rp; + fpu_status->FPUREG.Fpu_fsr_bits.tem = sfsr.u.fields.tem; +@@ -171,7 +171,7 @@ + sfsr.u.fields.fcc = fpu_status->FPUREG.Fpu_fsr_bits.fcc; + sfsr.u.fields.aexc = fpu_status->FPUREG.Fpu_fsr_bits.aexc; + sfsr.u.fields.cexc = fpu_status->FPUREG.Fpu_fsr_bits.cexc; +- sfsr.u.word = NXSwapLong(sfsr.u.word); ++ sfsr.u.word = OSSwapInt32(sfsr.u.word); + memcpy(&(fpu->fpu.Fpu_fsr), &sfsr, sizeof(struct swapped_fsr)); + } + } +Index: odcctools-9.2-ld/libmacho/swap.c +=================================================================== +--- odcctools-9.2-ld.orig/libmacho/swap.c 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/libmacho/swap.c 2013-09-03 21:08:01.877209515 +0000 +@@ -22,6 +22,7 @@ + */ + #ifndef RLD + #include <stdint.h> ++#include <libkern/OSByteOrder.h> + #include <mach-o/swap.h> + #include <string.h> + +@@ -30,8 +31,8 @@ + struct fat_header *fat_header, + enum NXByteOrder target_byte_sex) + { +- fat_header->magic = NXSwapLong(fat_header->magic); +- fat_header->nfat_arch = NXSwapLong(fat_header->nfat_arch); ++ fat_header->magic = OSSwapInt32(fat_header->magic); ++ fat_header->nfat_arch = OSSwapInt32(fat_header->nfat_arch); + } + + void +@@ -43,11 +44,11 @@ + uint32_t i; + + for(i = 0; i < nfat_arch; i++){ +- fat_archs[i].cputype = NXSwapLong(fat_archs[i].cputype); +- fat_archs[i].cpusubtype = NXSwapLong(fat_archs[i].cpusubtype); +- fat_archs[i].offset = NXSwapLong(fat_archs[i].offset); +- fat_archs[i].size = NXSwapLong(fat_archs[i].size); +- fat_archs[i].align = NXSwapLong(fat_archs[i].align); ++ fat_archs[i].cputype = OSSwapInt32(fat_archs[i].cputype); ++ fat_archs[i].cpusubtype = OSSwapInt32(fat_archs[i].cpusubtype); ++ fat_archs[i].offset = OSSwapInt32(fat_archs[i].offset); ++ fat_archs[i].size = OSSwapInt32(fat_archs[i].size); ++ fat_archs[i].align = OSSwapInt32(fat_archs[i].align); + } + } + +@@ -56,13 +57,13 @@ + struct mach_header *mh, + enum NXByteOrder target_byte_sex) + { +- mh->magic = NXSwapLong(mh->magic); +- mh->cputype = NXSwapLong(mh->cputype); +- mh->cpusubtype = NXSwapLong(mh->cpusubtype); +- mh->filetype = NXSwapLong(mh->filetype); +- mh->ncmds = NXSwapLong(mh->ncmds); +- mh->sizeofcmds = NXSwapLong(mh->sizeofcmds); +- mh->flags = NXSwapLong(mh->flags); ++ mh->magic = OSSwapInt32(mh->magic); ++ mh->cputype = OSSwapInt32(mh->cputype); ++ mh->cpusubtype = OSSwapInt32(mh->cpusubtype); ++ mh->filetype = OSSwapInt32(mh->filetype); ++ mh->ncmds = OSSwapInt32(mh->ncmds); ++ mh->sizeofcmds = OSSwapInt32(mh->sizeofcmds); ++ mh->flags = OSSwapInt32(mh->flags); + } + + void +@@ -70,14 +71,14 @@ + struct mach_header_64 *mh, + enum NXByteOrder target_byte_sex) + { +- mh->magic = NXSwapLong(mh->magic); +- mh->cputype = NXSwapLong(mh->cputype); +- mh->cpusubtype = NXSwapLong(mh->cpusubtype); +- mh->filetype = NXSwapLong(mh->filetype); +- mh->ncmds = NXSwapLong(mh->ncmds); +- mh->sizeofcmds = NXSwapLong(mh->sizeofcmds); +- mh->flags = NXSwapLong(mh->flags); +- mh->reserved = NXSwapLong(mh->reserved); ++ mh->magic = OSSwapInt32(mh->magic); ++ mh->cputype = OSSwapInt32(mh->cputype); ++ mh->cpusubtype = OSSwapInt32(mh->cpusubtype); ++ mh->filetype = OSSwapInt32(mh->filetype); ++ mh->ncmds = OSSwapInt32(mh->ncmds); ++ mh->sizeofcmds = OSSwapInt32(mh->sizeofcmds); ++ mh->flags = OSSwapInt32(mh->flags); ++ mh->reserved = OSSwapInt32(mh->reserved); + } + + void +@@ -85,8 +86,8 @@ + struct load_command *lc, + enum NXByteOrder target_byte_sex) + { +- lc->cmd = NXSwapLong(lc->cmd); +- lc->cmdsize = NXSwapLong(lc->cmdsize); ++ lc->cmd = OSSwapInt32(lc->cmd); ++ lc->cmdsize = OSSwapInt32(lc->cmdsize); + } + + void +@@ -95,16 +96,16 @@ + enum NXByteOrder target_byte_sex) + { + /* segname[16] */ +- sg->cmd = NXSwapLong(sg->cmd); +- sg->cmdsize = NXSwapLong(sg->cmdsize); +- sg->vmaddr = NXSwapLong(sg->vmaddr); +- sg->vmsize = NXSwapLong(sg->vmsize); +- sg->fileoff = NXSwapLong(sg->fileoff); +- sg->filesize = NXSwapLong(sg->filesize); +- sg->maxprot = NXSwapLong(sg->maxprot); +- sg->initprot = NXSwapLong(sg->initprot); +- sg->nsects = NXSwapLong(sg->nsects); +- sg->flags = NXSwapLong(sg->flags); ++ sg->cmd = OSSwapInt32(sg->cmd); ++ sg->cmdsize = OSSwapInt32(sg->cmdsize); ++ sg->vmaddr = OSSwapInt32(sg->vmaddr); ++ sg->vmsize = OSSwapInt32(sg->vmsize); ++ sg->fileoff = OSSwapInt32(sg->fileoff); ++ sg->filesize = OSSwapInt32(sg->filesize); ++ sg->maxprot = OSSwapInt32(sg->maxprot); ++ sg->initprot = OSSwapInt32(sg->initprot); ++ sg->nsects = OSSwapInt32(sg->nsects); ++ sg->flags = OSSwapInt32(sg->flags); + } + + void +@@ -113,16 +114,16 @@ + enum NXByteOrder target_byte_sex) + { + /* char segname[16] */ +- sg->cmd = NXSwapLong(sg->cmd); +- sg->cmdsize = NXSwapLong(sg->cmdsize); +- sg->vmaddr = NXSwapLongLong(sg->vmaddr); +- sg->vmsize = NXSwapLongLong(sg->vmsize); +- sg->fileoff = NXSwapLongLong(sg->fileoff); +- sg->filesize = NXSwapLongLong(sg->filesize); +- sg->maxprot = NXSwapLong(sg->maxprot); +- sg->initprot = NXSwapLong(sg->initprot); +- sg->nsects = NXSwapLong(sg->nsects); +- sg->flags = NXSwapLong(sg->flags); ++ sg->cmd = OSSwapInt32(sg->cmd); ++ sg->cmdsize = OSSwapInt32(sg->cmdsize); ++ sg->vmaddr = OSSwapInt64(sg->vmaddr); ++ sg->vmsize = OSSwapInt64(sg->vmsize); ++ sg->fileoff = OSSwapInt64(sg->fileoff); ++ sg->filesize = OSSwapInt64(sg->filesize); ++ sg->maxprot = OSSwapInt32(sg->maxprot); ++ sg->initprot = OSSwapInt32(sg->initprot); ++ sg->nsects = OSSwapInt32(sg->nsects); ++ sg->flags = OSSwapInt32(sg->flags); + } + + void +@@ -136,15 +137,15 @@ + for(i = 0; i < nsects; i++){ + /* sectname[16] */ + /* segname[16] */ +- s[i].addr = NXSwapLong(s[i].addr); +- s[i].size = NXSwapLong(s[i].size); +- s[i].offset = NXSwapLong(s[i].offset); +- s[i].align = NXSwapLong(s[i].align); +- s[i].reloff = NXSwapLong(s[i].reloff); +- s[i].nreloc = NXSwapLong(s[i].nreloc); +- s[i].flags = NXSwapLong(s[i].flags); +- s[i].reserved1 = NXSwapLong(s[i].reserved1); +- s[i].reserved2 = NXSwapLong(s[i].reserved2); ++ s[i].addr = OSSwapInt32(s[i].addr); ++ s[i].size = OSSwapInt32(s[i].size); ++ s[i].offset = OSSwapInt32(s[i].offset); ++ s[i].align = OSSwapInt32(s[i].align); ++ s[i].reloff = OSSwapInt32(s[i].reloff); ++ s[i].nreloc = OSSwapInt32(s[i].nreloc); ++ s[i].flags = OSSwapInt32(s[i].flags); ++ s[i].reserved1 = OSSwapInt32(s[i].reserved1); ++ s[i].reserved2 = OSSwapInt32(s[i].reserved2); + } + } + +@@ -159,16 +160,16 @@ + for(i = 0; i < nsects; i++){ + /* sectname[16] */ + /* segname[16] */ +- s[i].addr = NXSwapLongLong(s[i].addr); +- s[i].size = NXSwapLongLong(s[i].size); +- s[i].offset = NXSwapLong(s[i].offset); +- s[i].align = NXSwapLong(s[i].align); +- s[i].reloff = NXSwapLong(s[i].reloff); +- s[i].nreloc = NXSwapLong(s[i].nreloc); +- s[i].flags = NXSwapLong(s[i].flags); +- s[i].reserved1 = NXSwapLong(s[i].reserved1); +- s[i].reserved2 = NXSwapLong(s[i].reserved2); +- s[i].reserved3 = NXSwapLong(s[i].reserved3); ++ s[i].addr = OSSwapInt64(s[i].addr); ++ s[i].size = OSSwapInt64(s[i].size); ++ s[i].offset = OSSwapInt32(s[i].offset); ++ s[i].align = OSSwapInt32(s[i].align); ++ s[i].reloff = OSSwapInt32(s[i].reloff); ++ s[i].nreloc = OSSwapInt32(s[i].nreloc); ++ s[i].flags = OSSwapInt32(s[i].flags); ++ s[i].reserved1 = OSSwapInt32(s[i].reserved1); ++ s[i].reserved2 = OSSwapInt32(s[i].reserved2); ++ s[i].reserved3 = OSSwapInt32(s[i].reserved3); + } + } + +@@ -177,12 +178,12 @@ + struct symtab_command *st, + enum NXByteOrder target_byte_sex) + { +- st->cmd = NXSwapLong(st->cmd); +- st->cmdsize = NXSwapLong(st->cmdsize); +- st->symoff = NXSwapLong(st->symoff); +- st->nsyms = NXSwapLong(st->nsyms); +- st->stroff = NXSwapLong(st->stroff); +- st->strsize = NXSwapLong(st->strsize); ++ st->cmd = OSSwapInt32(st->cmd); ++ st->cmdsize = OSSwapInt32(st->cmdsize); ++ st->symoff = OSSwapInt32(st->symoff); ++ st->nsyms = OSSwapInt32(st->nsyms); ++ st->stroff = OSSwapInt32(st->stroff); ++ st->strsize = OSSwapInt32(st->strsize); + } + + void +@@ -190,26 +191,26 @@ + struct dysymtab_command *dyst, + enum NXByteOrder target_byte_sex) + { +- dyst->cmd = NXSwapLong(dyst->cmd); +- dyst->cmdsize = NXSwapLong(dyst->cmdsize); +- dyst->ilocalsym = NXSwapLong(dyst->ilocalsym); +- dyst->nlocalsym = NXSwapLong(dyst->nlocalsym); +- dyst->iextdefsym = NXSwapLong(dyst->iextdefsym); +- dyst->nextdefsym = NXSwapLong(dyst->nextdefsym); +- dyst->iundefsym = NXSwapLong(dyst->iundefsym); +- dyst->nundefsym = NXSwapLong(dyst->nundefsym); +- dyst->tocoff = NXSwapLong(dyst->tocoff); +- dyst->ntoc = NXSwapLong(dyst->ntoc); +- dyst->modtaboff = NXSwapLong(dyst->modtaboff); +- dyst->nmodtab = NXSwapLong(dyst->nmodtab); +- dyst->extrefsymoff = NXSwapLong(dyst->extrefsymoff); +- dyst->nextrefsyms = NXSwapLong(dyst->nextrefsyms); +- dyst->indirectsymoff = NXSwapLong(dyst->indirectsymoff); +- dyst->nindirectsyms = NXSwapLong(dyst->nindirectsyms); +- dyst->extreloff = NXSwapLong(dyst->extreloff); +- dyst->nextrel = NXSwapLong(dyst->nextrel); +- dyst->locreloff = NXSwapLong(dyst->locreloff); +- dyst->nlocrel = NXSwapLong(dyst->nlocrel); ++ dyst->cmd = OSSwapInt32(dyst->cmd); ++ dyst->cmdsize = OSSwapInt32(dyst->cmdsize); ++ dyst->ilocalsym = OSSwapInt32(dyst->ilocalsym); ++ dyst->nlocalsym = OSSwapInt32(dyst->nlocalsym); ++ dyst->iextdefsym = OSSwapInt32(dyst->iextdefsym); ++ dyst->nextdefsym = OSSwapInt32(dyst->nextdefsym); ++ dyst->iundefsym = OSSwapInt32(dyst->iundefsym); ++ dyst->nundefsym = OSSwapInt32(dyst->nundefsym); ++ dyst->tocoff = OSSwapInt32(dyst->tocoff); ++ dyst->ntoc = OSSwapInt32(dyst->ntoc); ++ dyst->modtaboff = OSSwapInt32(dyst->modtaboff); ++ dyst->nmodtab = OSSwapInt32(dyst->nmodtab); ++ dyst->extrefsymoff = OSSwapInt32(dyst->extrefsymoff); ++ dyst->nextrefsyms = OSSwapInt32(dyst->nextrefsyms); ++ dyst->indirectsymoff = OSSwapInt32(dyst->indirectsymoff); ++ dyst->nindirectsyms = OSSwapInt32(dyst->nindirectsyms); ++ dyst->extreloff = OSSwapInt32(dyst->extreloff); ++ dyst->nextrel = OSSwapInt32(dyst->nextrel); ++ dyst->locreloff = OSSwapInt32(dyst->locreloff); ++ dyst->nlocrel = OSSwapInt32(dyst->nlocrel); + } + + void +@@ -217,10 +218,10 @@ + struct symseg_command *ss, + enum NXByteOrder target_byte_sex) + { +- ss->cmd = NXSwapLong(ss->cmd); +- ss->cmdsize = NXSwapLong(ss->cmdsize); +- ss->offset = NXSwapLong(ss->offset); +- ss->size = NXSwapLong(ss->size); ++ ss->cmd = OSSwapInt32(ss->cmd); ++ ss->cmdsize = OSSwapInt32(ss->cmdsize); ++ ss->offset = OSSwapInt32(ss->offset); ++ ss->size = OSSwapInt32(ss->size); + } + + void +@@ -228,11 +229,11 @@ + struct fvmlib_command *fl, + enum NXByteOrder target_byte_sex) + { +- fl->cmd = NXSwapLong(fl->cmd); +- fl->cmdsize = NXSwapLong(fl->cmdsize); +- fl->fvmlib.name.offset = NXSwapLong(fl->fvmlib.name.offset); +- fl->fvmlib.minor_version = NXSwapLong(fl->fvmlib.minor_version); +- fl->fvmlib.header_addr = NXSwapLong(fl->fvmlib.header_addr); ++ fl->cmd = OSSwapInt32(fl->cmd); ++ fl->cmdsize = OSSwapInt32(fl->cmdsize); ++ fl->fvmlib.name.offset = OSSwapInt32(fl->fvmlib.name.offset); ++ fl->fvmlib.minor_version = OSSwapInt32(fl->fvmlib.minor_version); ++ fl->fvmlib.header_addr = OSSwapInt32(fl->fvmlib.header_addr); + } + + void +@@ -240,13 +241,13 @@ + struct dylib_command *dl, + enum NXByteOrder target_byte_sex) + { +- dl->cmd = NXSwapLong(dl->cmd); +- dl->cmdsize = NXSwapLong(dl->cmdsize); +- dl->dylib.name.offset = NXSwapLong(dl->dylib.name.offset); +- dl->dylib.timestamp = NXSwapLong(dl->dylib.timestamp); +- dl->dylib.current_version = NXSwapLong(dl->dylib.current_version); ++ dl->cmd = OSSwapInt32(dl->cmd); ++ dl->cmdsize = OSSwapInt32(dl->cmdsize); ++ dl->dylib.name.offset = OSSwapInt32(dl->dylib.name.offset); ++ dl->dylib.timestamp = OSSwapInt32(dl->dylib.timestamp); ++ dl->dylib.current_version = OSSwapInt32(dl->dylib.current_version); + dl->dylib.compatibility_version = +- NXSwapLong(dl->dylib.compatibility_version); ++ OSSwapInt32(dl->dylib.compatibility_version); + } + + void +@@ -254,9 +255,9 @@ + struct sub_framework_command *sub, + enum NXByteOrder target_byte_sex) + { +- sub->cmd = NXSwapLong(sub->cmd); +- sub->cmdsize = NXSwapLong(sub->cmdsize); +- sub->umbrella.offset = NXSwapLong(sub->umbrella.offset); ++ sub->cmd = OSSwapInt32(sub->cmd); ++ sub->cmdsize = OSSwapInt32(sub->cmdsize); ++ sub->umbrella.offset = OSSwapInt32(sub->umbrella.offset); + } + + void +@@ -264,9 +265,9 @@ + struct sub_umbrella_command *usub, + enum NXByteOrder target_byte_sex) + { +- usub->cmd = NXSwapLong(usub->cmd); +- usub->cmdsize = NXSwapLong(usub->cmdsize); +- usub->sub_umbrella.offset = NXSwapLong(usub->sub_umbrella.offset); ++ usub->cmd = OSSwapInt32(usub->cmd); ++ usub->cmdsize = OSSwapInt32(usub->cmdsize); ++ usub->sub_umbrella.offset = OSSwapInt32(usub->sub_umbrella.offset); + } + + void +@@ -274,9 +275,9 @@ + struct sub_library_command *lsub, + enum NXByteOrder target_byte_sex) + { +- lsub->cmd = NXSwapLong(lsub->cmd); +- lsub->cmdsize = NXSwapLong(lsub->cmdsize); +- lsub->sub_library.offset = NXSwapLong(lsub->sub_library.offset); ++ lsub->cmd = OSSwapInt32(lsub->cmd); ++ lsub->cmdsize = OSSwapInt32(lsub->cmdsize); ++ lsub->sub_library.offset = OSSwapInt32(lsub->sub_library.offset); + } + + void +@@ -284,9 +285,9 @@ + struct sub_client_command *csub, + enum NXByteOrder target_byte_sex) + { +- csub->cmd = NXSwapLong(csub->cmd); +- csub->cmdsize = NXSwapLong(csub->cmdsize); +- csub->client.offset = NXSwapLong(csub->client.offset); ++ csub->cmd = OSSwapInt32(csub->cmd); ++ csub->cmdsize = OSSwapInt32(csub->cmdsize); ++ csub->client.offset = OSSwapInt32(csub->client.offset); + } + + +@@ -295,12 +296,12 @@ + struct prebound_dylib_command *pbdylib, + enum NXByteOrder target_byte_sex) + { +- pbdylib->cmd = NXSwapLong(pbdylib->cmd); +- pbdylib->cmdsize = NXSwapLong(pbdylib->cmdsize); +- pbdylib->name.offset = NXSwapLong(pbdylib->name.offset); +- pbdylib->nmodules = NXSwapLong(pbdylib->nmodules); ++ pbdylib->cmd = OSSwapInt32(pbdylib->cmd); ++ pbdylib->cmdsize = OSSwapInt32(pbdylib->cmdsize); ++ pbdylib->name.offset = OSSwapInt32(pbdylib->name.offset); ++ pbdylib->nmodules = OSSwapInt32(pbdylib->nmodules); + pbdylib->linked_modules.offset = +- NXSwapLong(pbdylib->linked_modules.offset); ++ OSSwapInt32(pbdylib->linked_modules.offset); + } + + void +@@ -308,9 +309,9 @@ + struct dylinker_command *dyld, + enum NXByteOrder target_byte_sex) + { +- dyld->cmd = NXSwapLong(dyld->cmd); +- dyld->cmdsize = NXSwapLong(dyld->cmdsize); +- dyld->name.offset = NXSwapLong(dyld->name.offset); ++ dyld->cmd = OSSwapInt32(dyld->cmd); ++ dyld->cmdsize = OSSwapInt32(dyld->cmdsize); ++ dyld->name.offset = OSSwapInt32(dyld->name.offset); + } + + void +@@ -318,10 +319,10 @@ + struct fvmfile_command *ff, + enum NXByteOrder target_byte_sex) + { +- ff->cmd = NXSwapLong(ff->cmd); +- ff->cmdsize = NXSwapLong(ff->cmdsize); +- ff->name.offset = NXSwapLong(ff->name.offset); +- ff->header_addr = NXSwapLong(ff->header_addr); ++ ff->cmd = OSSwapInt32(ff->cmd); ++ ff->cmdsize = OSSwapInt32(ff->cmdsize); ++ ff->name.offset = OSSwapInt32(ff->name.offset); ++ ff->header_addr = OSSwapInt32(ff->header_addr); + } + + +@@ -330,8 +331,8 @@ + struct thread_command *ut, + enum NXByteOrder target_byte_sex) + { +- ut->cmd = NXSwapLong(ut->cmd); +- ut->cmdsize = NXSwapLong(ut->cmdsize); ++ ut->cmd = OSSwapInt32(ut->cmd); ++ ut->cmdsize = OSSwapInt32(ut->cmdsize); + } + + void +@@ -339,8 +340,8 @@ + struct ident_command *id_cmd, + enum NXByteOrder target_byte_sex) + { +- id_cmd->cmd = NXSwapLong(id_cmd->cmd); +- id_cmd->cmdsize = NXSwapLong(id_cmd->cmdsize); ++ id_cmd->cmd = OSSwapInt32(id_cmd->cmd); ++ id_cmd->cmdsize = OSSwapInt32(id_cmd->cmdsize); + } + + void +@@ -348,16 +349,16 @@ + struct routines_command *r_cmd, + enum NXByteOrder target_byte_sex) + { +- r_cmd->cmd = NXSwapLong(r_cmd->cmd); +- r_cmd->cmdsize = NXSwapLong(r_cmd->cmdsize); +- r_cmd->init_address = NXSwapLong(r_cmd->init_address); +- r_cmd->init_module = NXSwapLong(r_cmd->init_module); +- r_cmd->reserved1 = NXSwapLong(r_cmd->reserved1); +- r_cmd->reserved2 = NXSwapLong(r_cmd->reserved2); +- r_cmd->reserved3 = NXSwapLong(r_cmd->reserved3); +- r_cmd->reserved4 = NXSwapLong(r_cmd->reserved4); +- r_cmd->reserved5 = NXSwapLong(r_cmd->reserved5); +- r_cmd->reserved6 = NXSwapLong(r_cmd->reserved6); ++ r_cmd->cmd = OSSwapInt32(r_cmd->cmd); ++ r_cmd->cmdsize = OSSwapInt32(r_cmd->cmdsize); ++ r_cmd->init_address = OSSwapInt32(r_cmd->init_address); ++ r_cmd->init_module = OSSwapInt32(r_cmd->init_module); ++ r_cmd->reserved1 = OSSwapInt32(r_cmd->reserved1); ++ r_cmd->reserved2 = OSSwapInt32(r_cmd->reserved2); ++ r_cmd->reserved3 = OSSwapInt32(r_cmd->reserved3); ++ r_cmd->reserved4 = OSSwapInt32(r_cmd->reserved4); ++ r_cmd->reserved5 = OSSwapInt32(r_cmd->reserved5); ++ r_cmd->reserved6 = OSSwapInt32(r_cmd->reserved6); + } + + void +@@ -365,16 +366,16 @@ + struct routines_command_64 *r_cmd, + enum NXByteOrder target_byte_sex) + { +- r_cmd->cmd = NXSwapLong(r_cmd->cmd); +- r_cmd->cmdsize = NXSwapLong(r_cmd->cmdsize); +- r_cmd->init_address = NXSwapLongLong(r_cmd->init_address); +- r_cmd->init_module = NXSwapLongLong(r_cmd->init_module); +- r_cmd->reserved1 = NXSwapLongLong(r_cmd->reserved1); +- r_cmd->reserved2 = NXSwapLongLong(r_cmd->reserved2); +- r_cmd->reserved3 = NXSwapLongLong(r_cmd->reserved3); +- r_cmd->reserved4 = NXSwapLongLong(r_cmd->reserved4); +- r_cmd->reserved5 = NXSwapLongLong(r_cmd->reserved5); +- r_cmd->reserved6 = NXSwapLongLong(r_cmd->reserved6); ++ r_cmd->cmd = OSSwapInt32(r_cmd->cmd); ++ r_cmd->cmdsize = OSSwapInt32(r_cmd->cmdsize); ++ r_cmd->init_address = OSSwapInt64(r_cmd->init_address); ++ r_cmd->init_module = OSSwapInt64(r_cmd->init_module); ++ r_cmd->reserved1 = OSSwapInt64(r_cmd->reserved1); ++ r_cmd->reserved2 = OSSwapInt64(r_cmd->reserved2); ++ r_cmd->reserved3 = OSSwapInt64(r_cmd->reserved3); ++ r_cmd->reserved4 = OSSwapInt64(r_cmd->reserved4); ++ r_cmd->reserved5 = OSSwapInt64(r_cmd->reserved5); ++ r_cmd->reserved6 = OSSwapInt64(r_cmd->reserved6); + } + + void +@@ -382,9 +383,9 @@ + struct prebind_cksum_command *cksum_cmd, + enum NXByteOrder target_byte_sex) + { +- cksum_cmd->cmd = NXSwapLong(cksum_cmd->cmd); +- cksum_cmd->cmdsize = NXSwapLong(cksum_cmd->cmdsize); +- cksum_cmd->cksum = NXSwapLong(cksum_cmd->cksum); ++ cksum_cmd->cmd = OSSwapInt32(cksum_cmd->cmd); ++ cksum_cmd->cmdsize = OSSwapInt32(cksum_cmd->cmdsize); ++ cksum_cmd->cksum = OSSwapInt32(cksum_cmd->cksum); + } + + void +@@ -392,8 +393,8 @@ + struct uuid_command *uuid_cmd, + enum NXByteOrder target_byte_sex) + { +- uuid_cmd->cmd = NXSwapLong(uuid_cmd->cmd); +- uuid_cmd->cmdsize = NXSwapLong(uuid_cmd->cmdsize); ++ uuid_cmd->cmd = OSSwapInt32(uuid_cmd->cmd); ++ uuid_cmd->cmdsize = OSSwapInt32(uuid_cmd->cmdsize); + } + + void +@@ -405,11 +406,11 @@ + uint32_t i; + + for(i = 0; i < nsymbols; i++){ +- symbols[i].n_un.n_strx = NXSwapLong(symbols[i].n_un.n_strx); ++ symbols[i].n_un.n_strx = OSSwapInt32(symbols[i].n_un.n_strx); + /* n_type */ + /* n_sect */ +- symbols[i].n_desc = NXSwapShort(symbols[i].n_desc); +- symbols[i].n_value = NXSwapLong(symbols[i].n_value); ++ symbols[i].n_desc = OSSwapInt16(symbols[i].n_desc); ++ symbols[i].n_value = OSSwapInt32(symbols[i].n_value); + } + } + +@@ -422,11 +423,11 @@ + uint32_t i; + + for(i = 0; i < nsymbols; i++){ +- symbols[i].n_un.n_strx = NXSwapLong(symbols[i].n_un.n_strx); ++ symbols[i].n_un.n_strx = OSSwapInt32(symbols[i].n_un.n_strx); + /* n_type */ + /* n_sect */ +- symbols[i].n_desc = NXSwapShort(symbols[i].n_desc); +- symbols[i].n_value = NXSwapLongLong(symbols[i].n_value); ++ symbols[i].n_desc = OSSwapInt16(symbols[i].n_desc); ++ symbols[i].n_value = OSSwapInt64(symbols[i].n_value); + } + } + +@@ -439,8 +440,8 @@ + uint32_t i; + + for(i = 0; i < nranlibs; i++){ +- ranlibs[i].ran_un.ran_strx = NXSwapLong(ranlibs[i].ran_un.ran_strx); +- ranlibs[i].ran_off = NXSwapLong(ranlibs[i].ran_off); ++ ranlibs[i].ran_un.ran_strx = OSSwapInt32(ranlibs[i].ran_un.ran_strx); ++ ranlibs[i].ran_off = OSSwapInt32(ranlibs[i].ran_off); + } + } + +@@ -455,7 +456,7 @@ + uint32_t to_host_byte_sex, scattered; + + struct swapped_relocation_info { +- long r_address; ++ uint32_t r_address; + union { + struct { + unsigned int +@@ -471,7 +472,7 @@ + + struct swapped_scattered_relocation_info { + uint32_t word; +- long r_value; ++ uint32_t r_value; + } *ssr; + + host_byte_sex = NXHostByteOrder(); +@@ -479,14 +480,14 @@ + + for(i = 0; i < nrelocs; i++){ + if(to_host_byte_sex) +- scattered = (NXSwapLong(relocs[i].r_address) & R_SCATTERED) != 0; ++ scattered = (OSSwapInt32(relocs[i].r_address) & R_SCATTERED) != 0; + else + scattered = ((relocs[i].r_address) & R_SCATTERED) != 0; + if(scattered == FALSE){ + if(to_host_byte_sex){ + memcpy(&sr, relocs + i, sizeof(struct relocation_info)); +- sr.r_address = NXSwapLong(sr.r_address); +- sr.u.word = NXSwapLong(sr.u.word); ++ sr.r_address = OSSwapInt32(sr.r_address); ++ sr.u.word = OSSwapInt32(sr.u.word); + relocs[i].r_address = sr.r_address; + relocs[i].r_symbolnum = sr.u.fields.r_symbolnum; + relocs[i].r_pcrel = sr.u.fields.r_pcrel; +@@ -501,15 +502,15 @@ + sr.u.fields.r_pcrel = relocs[i].r_pcrel; + sr.u.fields.r_extern = relocs[i].r_extern; + sr.u.fields.r_type = relocs[i].r_type; +- sr.r_address = NXSwapLong(sr.r_address); +- sr.u.word = NXSwapLong(sr.u.word); ++ sr.r_address = OSSwapInt32(sr.r_address); ++ sr.u.word = OSSwapInt32(sr.u.word); + memcpy(relocs + i, &sr, sizeof(struct relocation_info)); + } + } + else{ + ssr = (struct swapped_scattered_relocation_info *)(relocs + i); +- ssr->word = NXSwapLong(ssr->word); +- ssr->r_value = NXSwapLong(ssr->r_value); ++ ssr->word = OSSwapInt32(ssr->word); ++ ssr->r_value = OSSwapInt32(ssr->r_value); + } + } + } +@@ -523,7 +524,7 @@ + uint32_t i; + + for(i = 0; i < nindirect_symbols; i++) +- indirect_symbols[i] = NXSwapLong(indirect_symbols[i]); ++ indirect_symbols[i] = OSSwapInt32(indirect_symbols[i]); + } + + void +@@ -551,14 +552,14 @@ + for(i = 0; i < nrefs; i++){ + if(target_byte_sex == host_byte_sex){ + memcpy(&sref, refs + i, sizeof(struct swapped_dylib_reference)); +- sref.u.word = NXSwapLong(sref.u.word); ++ sref.u.word = OSSwapInt32(sref.u.word); + refs[i].flags = sref.u.fields.flags; + refs[i].isym = sref.u.fields.isym; + } + else{ + sref.u.fields.isym = refs[i].isym; + sref.u.fields.flags = refs[i].flags; +- sref.u.word = NXSwapLong(sref.u.word); ++ sref.u.word = OSSwapInt32(sref.u.word); + memcpy(refs + i, &sref, sizeof(struct swapped_dylib_reference)); + } + } +@@ -574,19 +575,19 @@ + uint32_t i; + + for(i = 0; i < nmods; i++){ +- mods[i].module_name = NXSwapLong(mods[i].module_name); +- mods[i].iextdefsym = NXSwapLong(mods[i].iextdefsym); +- mods[i].nextdefsym = NXSwapLong(mods[i].nextdefsym); +- mods[i].irefsym = NXSwapLong(mods[i].irefsym); +- mods[i].nrefsym = NXSwapLong(mods[i].nrefsym); +- mods[i].ilocalsym = NXSwapLong(mods[i].ilocalsym); +- mods[i].nlocalsym = NXSwapLong(mods[i].nlocalsym); +- mods[i].iextrel = NXSwapLong(mods[i].iextrel); +- mods[i].nextrel = NXSwapLong(mods[i].nextrel); +- mods[i].iinit_iterm = NXSwapLong(mods[i].iinit_iterm); +- mods[i].ninit_nterm = NXSwapLong(mods[i].ninit_nterm); +- mods[i].objc_module_info_size = NXSwapLong(mods[i].objc_module_info_size); +- mods[i].objc_module_info_addr = NXSwapLong(mods[i].objc_module_info_addr); ++ mods[i].module_name = OSSwapInt32(mods[i].module_name); ++ mods[i].iextdefsym = OSSwapInt32(mods[i].iextdefsym); ++ mods[i].nextdefsym = OSSwapInt32(mods[i].nextdefsym); ++ mods[i].irefsym = OSSwapInt32(mods[i].irefsym); ++ mods[i].nrefsym = OSSwapInt32(mods[i].nrefsym); ++ mods[i].ilocalsym = OSSwapInt32(mods[i].ilocalsym); ++ mods[i].nlocalsym = OSSwapInt32(mods[i].nlocalsym); ++ mods[i].iextrel = OSSwapInt32(mods[i].iextrel); ++ mods[i].nextrel = OSSwapInt32(mods[i].nextrel); ++ mods[i].iinit_iterm = OSSwapInt32(mods[i].iinit_iterm); ++ mods[i].ninit_nterm = OSSwapInt32(mods[i].ninit_nterm); ++ mods[i].objc_module_info_size = OSSwapInt32(mods[i].objc_module_info_size); ++ mods[i].objc_module_info_addr = OSSwapInt32(mods[i].objc_module_info_addr); + } + } + +@@ -599,19 +600,19 @@ + uint32_t i; + + for(i = 0; i < nmods; i++){ +- mods[i].module_name = NXSwapLong(mods[i].module_name); +- mods[i].iextdefsym = NXSwapLong(mods[i].iextdefsym); +- mods[i].nextdefsym = NXSwapLong(mods[i].nextdefsym); +- mods[i].irefsym = NXSwapLong(mods[i].irefsym); +- mods[i].nrefsym = NXSwapLong(mods[i].nrefsym); +- mods[i].ilocalsym = NXSwapLong(mods[i].ilocalsym); +- mods[i].nlocalsym = NXSwapLong(mods[i].nlocalsym); +- mods[i].iextrel = NXSwapLong(mods[i].iextrel); +- mods[i].nextrel = NXSwapLong(mods[i].nextrel); +- mods[i].iinit_iterm = NXSwapLong(mods[i].iinit_iterm); +- mods[i].ninit_nterm = NXSwapLong(mods[i].ninit_nterm); +- mods[i].objc_module_info_size = NXSwapLong(mods[i].objc_module_info_size); +- mods[i].objc_module_info_addr = NXSwapLongLong(mods[i].objc_module_info_addr); ++ mods[i].module_name = OSSwapInt32(mods[i].module_name); ++ mods[i].iextdefsym = OSSwapInt32(mods[i].iextdefsym); ++ mods[i].nextdefsym = OSSwapInt32(mods[i].nextdefsym); ++ mods[i].irefsym = OSSwapInt32(mods[i].irefsym); ++ mods[i].nrefsym = OSSwapInt32(mods[i].nrefsym); ++ mods[i].ilocalsym = OSSwapInt32(mods[i].ilocalsym); ++ mods[i].nlocalsym = OSSwapInt32(mods[i].nlocalsym); ++ mods[i].iextrel = OSSwapInt32(mods[i].iextrel); ++ mods[i].nextrel = OSSwapInt32(mods[i].nextrel); ++ mods[i].iinit_iterm = OSSwapInt32(mods[i].iinit_iterm); ++ mods[i].ninit_nterm = OSSwapInt32(mods[i].ninit_nterm); ++ mods[i].objc_module_info_size = OSSwapInt32(mods[i].objc_module_info_size); ++ mods[i].objc_module_info_addr = OSSwapInt64(mods[i].objc_module_info_addr); + } + } + +@@ -624,8 +625,8 @@ + uint32_t i; + + for(i = 0; i < ntocs; i++){ +- tocs[i].symbol_index = NXSwapLong(tocs[i].symbol_index); +- tocs[i].module_index = NXSwapLong(tocs[i].module_index); ++ tocs[i].symbol_index = OSSwapInt32(tocs[i].symbol_index); ++ tocs[i].module_index = OSSwapInt32(tocs[i].module_index); + } + } + #endif /* !defined(RLD) */ +Index: odcctools-9.2-ld/include/mach/machine.h +=================================================================== +--- odcctools-9.2-ld.orig/include/mach/machine.h 2013-09-03 21:08:01.481209525 +0000 ++++ odcctools-9.2-ld/include/mach/machine.h 2013-09-03 21:08:01.881209515 +0000 +@@ -302,7 +302,14 @@ + #define CPU_SUBTYPE_ARM_A500 ((cpu_subtype_t) 2) + #define CPU_SUBTYPE_ARM_A440 ((cpu_subtype_t) 3) + #define CPU_SUBTYPE_ARM_M4 ((cpu_subtype_t) 4) +-#define CPU_SUBTYPE_ARM_A680 ((cpu_subtype_t) 5) ++#define CPU_SUBTYPE_ARM_V4T ((cpu_subtype_t) 5) ++#define CPU_SUBTYPE_ARM_V6 ((cpu_subtype_t) 6) ++#define CPU_SUBTYPE_ARM_V5TEJ ((cpu_subtype_t) 7) ++#define CPU_SUBTYPE_ARM_XSCALE ((cpu_subtype_t) 8) ++#define CPU_SUBTYPE_ARM_V7 ((cpu_subtype_t) 9) ++#define CPU_SUBTYPE_ARM_V7F ((cpu_subtype_t) 10) /* Cortex A9 */ ++#define CPU_SUBTYPE_ARM_V7S ((cpu_subtype_t) 11) /* Swift */ ++#define CPU_SUBTYPE_ARM_V7K ((cpu_subtype_t) 12) /* Kirkwood40 */ + + /* + * MC88000 subtypes +@@ -380,11 +387,4 @@ + #define CPU_SUBTYPE_VEO_4 ((cpu_subtype_t) 4) + #define CPU_SUBTYPE_VEO_ALL CPU_SUBTYPE_VEO_2 + +-#define CPU_SUBTYPE_ARM_V4T ((cpu_subtype_t) 5) +-#define CPU_SUBTYPE_ARM_V6 ((cpu_subtype_t) 6) +-#define CPU_SUBTYPE_ARM_V5TEJ ((cpu_subtype_t) 7) +-#define CPU_SUBTYPE_ARM_XSCALE ((cpu_subtype_t) 8) +-#define CPU_SUBTYPE_ARM_ALL ((cpu_subtype_t) 0) +- +- + #endif /* _MACH_MACHINE_H_ */ +Index: odcctools-9.2-ld/ar/archive.c +=================================================================== +--- odcctools-9.2-ld.orig/ar/archive.c 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/ar/archive.c 2013-09-03 21:08:01.881209515 +0000 +@@ -114,6 +114,9 @@ + if ((fd = open(archive, mode, DEFFILEMODE)) < 0) + error(archive); + ++ if((mode & O_ACCMODE) == O_RDONLY) ++ goto skip_flock; ++ + /* + * Attempt to place a lock on the opened file - if we get an + * error then someone is already working on this library (or +@@ -121,6 +124,18 @@ + */ + opened: + r = flock(fd, LOCK_EX|LOCK_NB); ++ if (r && errno == EAGAIN) { ++ /* ++ * If we get EAGAIN sleep for a second and loop up to 10 times ++ * trying again. ++ */ ++ static int tries = 0; ++ ++ sleep(1); ++ tries++; ++ if (tries < 10) ++ goto opened; ++ } + if (r) { + switch (errno) + { +@@ -152,12 +167,13 @@ + /* Locking seems to not be working */ + case ENOTSUP: + case EHOSTUNREACH: +- /*case EBADRPC:*/ ++ /* case EBADRPC: */ + default: + /* Filesystem does not support locking */ + break; + } + } ++skip_flock: + + /* + * If not created, O_RDONLY|O_RDWR indicates that it has to be +@@ -170,8 +186,8 @@ + badfmt(); + error(archive); + } else if (bcmp(buf, ARMAG, SARMAG)) { +- unsigned long magic; +- memcpy(&magic, buf, sizeof(unsigned long)); ++ uint32_t magic; ++ memcpy(&magic, buf, sizeof(uint32_t)); + #ifdef __BIG_ENDIAN__ + if(magic == FAT_MAGIC) + #endif /* __BIG_ENDIAN__ */ +@@ -288,6 +304,7 @@ + char *name; + struct ar_hdr *hdr; + off_t size; ++ long int tv_sec; + + /* + * If passed an sb structure, reading a file from disk. Get stat(2) +@@ -299,6 +316,8 @@ + name = rname(cfp->rname); + (void)fstat(cfp->rfd, sb); + ++ tv_sec = (long int)0; ++ + /* + * If not truncating names and the name is too long or contains + * a space, use extended format 1. +@@ -311,24 +330,24 @@ + name, OLDARMAXNAME, name); + (void)fflush(stderr); + } +- (void)sprintf(hb, HDR3, name, (long int)sb->st_mtime, ++ (void)sprintf(hb, HDR3, name, (long int)tv_sec, + (unsigned int)(u_short)sb->st_uid, + (unsigned int)(u_short)sb->st_gid, +- sb->st_mode, (long long int) sb->st_size, ARFMAG); ++ sb->st_mode, sb->st_size, ARFMAG); + lname = 0; + } else if (lname > sizeof(hdr->ar_name) || strchr(name, ' ')) + (void)sprintf(hb, HDR1, AR_EFMT1, (lname + 3) & ~3, +- (long int)sb->st_mtime, ++ (long int)tv_sec, + (unsigned int)(u_short)sb->st_uid, + (unsigned int)(u_short)sb->st_gid, +- sb->st_mode, (long long int) sb->st_size + ((lname + 3) & ~3), ++ sb->st_mode, sb->st_size + ((lname + 3) & ~3), + ARFMAG); + else { + lname = 0; +- (void)sprintf(hb, HDR2, name, (long int)sb->st_mtime, ++ (void)sprintf(hb, HDR2, name, (long int)tv_sec, + (unsigned int)(u_short)sb->st_uid, + (unsigned int)(u_short)sb->st_gid, +- sb->st_mode, (long long int) sb->st_size, ARFMAG); ++ sb->st_mode, sb->st_size, ARFMAG); + } + size = sb->st_size; + } else { +Index: odcctools-9.2-ld/ar/archive.h +=================================================================== +--- odcctools-9.2-ld.orig/ar/archive.h 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/ar/archive.h 2013-09-03 21:08:01.881209515 +0000 +@@ -121,10 +121,6 @@ + + #include <sys/cdefs.h> + +-#if defined(__CYGWIN__) +-#define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)/* 0666*/ +-#endif +- + struct stat; + + void close_archive __P((int)); +Index: odcctools-9.2-ld/as/app.c +=================================================================== +--- odcctools-9.2-ld.orig/as/app.c 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/as/app.c 2013-09-03 21:08:01.881209515 +0000 +@@ -70,6 +70,7 @@ + memset(lex, '\0', sizeof(lex)); /* Trust NOBODY! */ + lex [' '] |= LEX_IS_WHITESPACE; + lex ['\t'] |= LEX_IS_WHITESPACE; ++ lex ['\r'] |= LEX_IS_WHITESPACE; + for (p =symbol_chars;*p;++p) + lex [(int)*p] |= LEX_IS_SYMBOL_COMPONENT; + lex ['\n'] |= LEX_IS_LINE_SEPERATOR; +@@ -289,6 +290,9 @@ + do ch= getc_unlocked(fp); + while(ch!='\n'); + state=0; ++#ifdef I386 ++ substate = 0; ++#endif + return ch; + } + +@@ -403,8 +407,12 @@ + return *out_string++; + + case ':': +- if(state!=3) ++ if(state!=3) { + state=0; ++#ifdef I386 ++ substate = 0; ++#endif ++ } + return ch; + + case '\n': +@@ -419,6 +427,9 @@ + case ';': + #endif + state=0; ++#ifdef I386 ++ substate = 0; ++#endif + return ch; + + default: +@@ -465,6 +476,9 @@ + if(ch==EOF) + as_warn("EOF in Comment: Newline inserted"); + state=0; ++#ifdef I386 ++ substate = 0; ++#endif + return '\n'; + } + ungetc(ch, fp); +@@ -479,6 +493,9 @@ + if(ch==EOF) + as_warn("EOF in comment: Newline inserted"); + state=0; ++#ifdef I386 ++ substate = 0; ++#endif + return '\n'; + + } else if(state==0) { +@@ -658,6 +675,9 @@ + do ch= scrub_from_string(); + while(ch!='\n'); + state=0; ++#ifdef I386 ++ substate = 0; ++#endif + return ch; + } + +@@ -757,8 +777,12 @@ + return *out_string++; + + case ':': +- if(state!=3) ++ if(state!=3) { + state=0; ++#ifdef I386 ++ substate = 0; ++#endif ++ } + return ch; + + case '\n': +@@ -773,6 +797,9 @@ + case ';': + #endif + state=0; ++#ifdef I386 ++ substate = 0; ++#endif + return ch; + + default: +@@ -792,6 +819,9 @@ + if(ch==EOF) + as_warn("EOF in Comment: Newline inserted"); + state=0; ++#ifdef I386 ++ substate = 0; ++#endif + return '\n'; + } + scrub_to_string(ch); +@@ -806,6 +836,9 @@ + if(ch==EOF) + as_warn("EOF in comment: Newline inserted"); + state=0; ++#ifdef I386 ++ substate = 0; ++#endif + return '\n'; + + } else if(state==0) { +Index: odcctools-9.2-ld/as/as.c +=================================================================== +--- odcctools-9.2-ld.orig/as/as.c 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/as/as.c 2013-09-03 21:08:01.881209515 +0000 +@@ -46,8 +46,12 @@ + #include "xmalloc.h" + #include "layout.h" + #include "write_object.h" ++#include "dwarf2dbg.h" + #include "stuff/arch.h" + ++/* Used for --gdwarf2 to generate dwarf2 debug info for assembly source files */ ++enum debug_info_type debug_type = DEBUG_NONE; ++ + /* ['x'] TRUE if "-x" seen. */ + char flagseen[128] = { 0 }; + +@@ -76,10 +80,11 @@ + struct directory_stack *include = NULL; /* First dir to search */ + static struct directory_stack *include_tail = NULL; /* Last in chain */ + +-/* apple_version is in apple_version.c which is created by the Makefile */ +-extern char apple_version[]; +-/* this is only used here, thus defined here (was in version.c in GAS) */ +-static char version_string[] = "GNU assembler version 1.38\n"; ++/* this is only used here, and in dwarf2dbg.c as the producer */ ++char version_string[] = "GNU assembler version 1.38"; ++ ++/* this is set here, and used in dwarf2dbg.c as the apple_flags */ ++char *apple_flags = NULL; + + /* + * The list of signals to catch if not ignored. +@@ -109,7 +114,7 @@ + char *arg; /* an arg to program */ + char a; /* an arg flag (after -) */ + char *out_file_name;/* name of object file, argument to -o if specified */ +- int i; ++ int i, apple_flags_size; + struct directory_stack *dirtmp; + + progname = argv[0]; +@@ -129,6 +134,20 @@ + /* This is the -dynamic flag, which is now the default */ + flagseen[(int)'k'] = TRUE; + ++ if(getenv("RC_DEBUG_OPTIONS") != NULL){ ++ apple_flags_size = 1; ++ for(i = 0; i < argc; i++) ++ apple_flags_size += strlen(argv[i]) + 2; ++ apple_flags = xmalloc(apple_flags_size); ++ apple_flags_size = 0; ++ for(i = 0; i < argc; i++){ ++ strcpy(apple_flags + apple_flags_size, argv[i]); ++ apple_flags_size += strlen(argv[i]); ++ apple_flags[apple_flags_size++] = ' '; ++ } ++ apple_flags[apple_flags_size] = '\0'; ++ } ++ + /* + * Parse arguments, but we are only interested in flags. + * When we find a flag, we process it then make it's argv[] NULL. +@@ -156,8 +175,10 @@ + *work_argv = NULL; /* NULL means 'not a file-name' */ + continue; + } +- if(strcmp(arg, "--gdwarf2") == 0){ +- as_fatal("%s: I don't understand %s flag!", progname, arg); ++ if(strcmp(arg, "--gdwarf2") == 0 || strcmp(arg, "-gdwarf-2") == 0){ ++ debug_type = DEBUG_DWARF2; ++ *work_argv = NULL; /* NULL means 'not a file-name' */ ++ continue; + } + + /* Keep scanning args looking for flags. */ +@@ -179,7 +200,7 @@ + (a != 'd') && (a != 's') && (a != 'k')) + as_warn("%s: Flag option -%c has already been seen!", + progname, a); +- if(a != 'f' && a != 'n') ++ if(a != 'f' && a != 'n' && a != 'g') + flagseen[(int)a] = TRUE; + switch(a){ + case 'f': +@@ -217,9 +238,8 @@ + break; + + case 'v': +- fprintf(stderr,"Apple Computer, Inc. version " +- "%s, ", apple_version); +- fprintf(stderr, version_string); ++ fprintf(stderr, APPLE_INC_VERSION " %s, ", apple_version); ++ fprintf(stderr, "%s\n", version_string); + if(*arg && strcmp(arg,"ersion")) + as_fatal("Unknown -v option ignored"); + while(*arg) +@@ -258,7 +278,10 @@ + break; + + case 'g': +- /* generate stabs for debugging assembly code */ ++ /* -g no longer means generate stabs for debugging ++ assembly code but to generate dwarf2 for assembly code. ++ If stabs if really wanted then --gstabs can be used. */ ++ debug_type = DEBUG_DWARF2; + break; + + case 'n': +@@ -683,6 +706,50 @@ + archflag_cpusubtype = + CPU_SUBTYPE_ARM_V6; + } ++ else if(strcmp(*work_argv, ++ "armv7") == 0){ ++ if(archflag_cpusubtype != -1 && ++ archflag_cpusubtype != ++ CPU_SUBTYPE_ARM_V7) ++ as_fatal("can't specify more " ++ "than one -arch flag "); ++ specific_archflag = *work_argv; ++ archflag_cpusubtype = ++ CPU_SUBTYPE_ARM_V7; ++ } ++ else if(strcmp(*work_argv, ++ "armv7f") == 0){ ++ if(archflag_cpusubtype != -1 && ++ archflag_cpusubtype != ++ CPU_SUBTYPE_ARM_V7F) ++ as_fatal("can't specify more " ++ "than one -arch flag "); ++ specific_archflag = *work_argv; ++ archflag_cpusubtype = ++ CPU_SUBTYPE_ARM_V7F; ++ } ++ else if(strcmp(*work_argv, ++ "armv7s") == 0){ ++ if(archflag_cpusubtype != -1 && ++ archflag_cpusubtype != ++ CPU_SUBTYPE_ARM_V7S) ++ as_fatal("can't specify more " ++ "than one -arch flag "); ++ specific_archflag = *work_argv; ++ archflag_cpusubtype = ++ CPU_SUBTYPE_ARM_V7S; ++ } ++ else if(strcmp(*work_argv, ++ "armv7k") == 0){ ++ if(archflag_cpusubtype != -1 && ++ archflag_cpusubtype != ++ CPU_SUBTYPE_ARM_V7K) ++ as_fatal("can't specify more " ++ "than one -arch flag "); ++ specific_archflag = *work_argv; ++ archflag_cpusubtype = ++ CPU_SUBTYPE_ARM_V7K; ++ } + else + as_fatal("I expected 'arm' after " + "-arch for this assembler."); +@@ -753,6 +820,12 @@ + perform_an_assembly_pass(argc, argv); /* Assemble it. */ + + if(seen_at_least_1_file() && bad_error != TRUE){ ++ /* ++ * If we've been collecting dwarf2 .debug_line info, either for ++ * assembly debugging or on behalf of the compiler, emit it now. ++ */ ++ dwarf2_finish(); ++ + layout_addresses(); + write_object(out_file_name); + } +Index: odcctools-9.2-ld/as/driver.c +=================================================================== +--- odcctools-9.2-ld.orig/as/driver.c 2013-09-03 21:08:01.409209526 +0000 ++++ odcctools-9.2-ld/as/driver.c 2013-09-03 21:08:01.881209515 +0000 +@@ -45,8 +45,8 @@ + #endif + const char *AS = "/as"; + +- int i; +- unsigned long count, verbose; ++ int i, j; ++ uint32_t count, verbose, run_clang; + char *p, c, *arch_name, *as, *as_local; + char *prefix, buf[MAXPATHLEN], resolved_name[PATH_MAX]; + uint32_t bufsize; +Index: odcctools-9.2-ld/as/i386.c +=================================================================== +--- odcctools-9.2-ld.orig/as/i386.c 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/as/i386.c 2013-09-03 21:08:01.885209515 +0000 +@@ -158,7 +158,7 @@ + #endif + #ifdef ARCH64 + #ifdef NeXT_MOD +-static symbolS *x86_64_resolve_local_symbol(const symbolS *sym); ++static symbolS *x86_64_resolve_local_symbol(symbolS *sym); + #endif + #endif + +@@ -1022,7 +1022,7 @@ + } + + #ifndef NeXT_MOD +-unsigned long ++uint32_t + i386_mach () + { + if (!strcmp (default_arch, "x86_64")) +@@ -1266,7 +1266,7 @@ + { + fprintf (stdout, " operation %d\n", e->X_op); + fprintf (stdout, " add_number %ld (%lx)\n", +- (long) e->X_add_number, (long) e->X_add_number); ++ (int32_t) e->X_add_number, (int32_t) e->X_add_number); + if (e->X_add_symbol) + { + fprintf (stdout, " add_symbol "); +@@ -1377,7 +1377,7 @@ + case 4: return BFD_RELOC_32_PCREL; + #endif + } +- as_bad (_("can not do %d byte pc-relative relocation"), size); ++ as_bad (_("cannot do %d byte pc-relative relocation"), size); + } + else + { +@@ -1408,7 +1408,7 @@ + case 8: return BFD_RELOC_64; + #endif + } +- as_bad (_("can not do %s %d byte relocation"), ++ as_bad (_("cannot do %s %d byte relocation"), + sign ? "signed" : "unsigned", size); + } + +@@ -5893,7 +5893,7 @@ + next instruction. That is, the address of the offset, plus its + size, since the offset is always the last part of the insn. */ + +-long ++int32_t + md_pcrel_from (fixP) + #ifdef NeXT_MOD + const +@@ -5965,7 +5965,7 @@ + #if ARCH64 + static + symbolS * +-x86_64_resolve_local_symbol(const symbolS *sym) ++x86_64_resolve_local_symbol(symbolS *sym) + { + symbolS *prev_symbol; + for (prev_symbol = sym->sy_prev_by_index; prev_symbol != NULL; prev_symbol = prev_symbol->sy_prev_by_index) +@@ -5988,7 +5988,7 @@ + return prev_symbol; + } + +-long ++int32_t + x86_64_fixup_symbol(fixS *fix, int nsect, symbolS **sym) + { + /* +Index: odcctools-9.2-ld/as/i386.h +=================================================================== +--- odcctools-9.2-ld.orig/as/i386.h 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/as/i386.h 2013-09-03 21:08:01.885209515 +0000 +@@ -43,8 +43,9 @@ + #define ADDR_PREFIX 2 + #define DATA_PREFIX 3 + #define SEG_PREFIX 4 +-#define REX_PREFIX 5 /* must come last. */ +-#define MAX_PREFIXES 6 /* max prefixes per opcode */ ++#define MAN_PREFIX 5 /* 0xf2,0xf3,etc "mandatory" prefix, not REPs */ ++#define REX_PREFIX 6 /* must come last. */ ++#define MAX_PREFIXES 7 /* max prefixes per opcode */ + + /* we define the syntax here (modulo base,index,scale syntax) */ + #define REGISTER_PREFIX '%' +@@ -366,7 +367,7 @@ + + #ifdef NeXT_MOD + #if ARCH64 +-long x86_64_fixup_symbol PARAMS ((fixS *, int, struct symbol **)); ++int32_t x86_64_fixup_symbol PARAMS ((fixS *, int, struct symbol **)); + #define TC_FIXUP_SYMBOL(FIX, SECT, SYM) x86_64_fixup_symbol(FIX, SECT, SYM) + #endif + #endif +Index: odcctools-9.2-ld/as/dwarf2dbg.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ odcctools-9.2-ld/as/dwarf2dbg.c 2013-09-03 21:08:01.885209515 +0000 +@@ -0,0 +1,2298 @@ ++/* dwarf2dbg.c - DWARF2 debug support ++ Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 ++ Free Software Foundation, Inc. ++ Contributed by David Mosberger-Tang <davidm@hpl.hp.com> ++ ++ This file is part of GAS, the GNU Assembler. ++ ++ GAS is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2, or (at your option) ++ any later version. ++ ++ GAS is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with GAS; see the file COPYING. If not, write to the Free ++ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA ++ 02110-1301, USA. */ ++ ++/* Logical line numbers can be controlled by the compiler via the ++ following directives: ++ ++ .file FILENO "file.c" ++ .loc FILENO LINENO [COLUMN] [basic_block] [prologue_end] \ ++ [epilogue_begin] [is_stmt VALUE] [isa VALUE] ++*/ ++ ++#include <stdlib.h> ++#include <string.h> ++#include <unistd.h> ++#include <sys/param.h> ++#include <libgen.h> ++#define ATTRIBUTE_UNUSED ++#define NO_LISTING ++ ++#include "as.h" ++#include "md.h" ++#include "obstack.h" ++/* Use ctype.h and these directly instead of "safe-ctype.h" */ ++#include "ctype.h" ++#define ISALPHA(c) isalpha(c) ++#define ISDIGIT(c) isdigit(c) ++ ++#ifdef HAVE_LIMITS_H ++#include <limits.h> ++#else ++#ifdef HAVE_SYS_PARAM_H ++#include <sys/param.h> ++#endif ++#ifndef INT_MAX ++#define INT_MAX (int) (((unsigned) (-1)) >> 1) ++#endif ++#endif ++ ++#include "dwarf2dbg.h" ++#include <filenames.h> ++ ++#ifdef HAVE_DOS_BASED_FILE_SYSTEM ++/* We need to decide which character to use as a directory separator. ++ Just because HAVE_DOS_BASED_FILE_SYSTEM is defined, it does not ++ necessarily mean that the backslash character is the one to use. ++ Some environments, eg Cygwin, can support both naming conventions. ++ So we use the heuristic that we only need to use the backslash if ++ the path is an absolute path starting with a DOS style drive ++ selector. eg C: or D: */ ++# define INSERT_DIR_SEPARATOR(string, offset) \ ++ do \ ++ { \ ++ if (offset > 1 \ ++ && string[0] != 0 \ ++ && string[1] == ':') \ ++ string [offset] = '\\'; \ ++ else \ ++ string [offset] = '/'; \ ++ } \ ++ while (0) ++#else ++# define INSERT_DIR_SEPARATOR(string, offset) string[offset] = '/' ++#endif ++ ++#ifndef DWARF2_FORMAT ++# define DWARF2_FORMAT() dwarf2_format_32bit ++#endif ++ ++#ifndef DWARF2_ADDR_SIZE ++# define DWARF2_ADDR_SIZE(bfd) (bfd_arch_bits_per_address (bfd) / 8) ++#endif ++ ++#include "sections.h" ++#include "frags.h" ++#include "read.h" ++#include "xmalloc.h" ++#include "input-scrub.h" ++#include "messages.h" ++#include "symbols.h" ++#include "layout.h" ++ ++#include "elf/dwarf2.h" ++ ++/* Since we can't generate the prolog until the body is complete, we ++ use three different subsegments for .debug_line: one holding the ++ prolog, one for the directory and filename info, and one for the ++ body ("statement program"). */ ++#define DL_PROLOG 0 ++#define DL_FILES 1 ++#define DL_BODY 2 ++ ++/* If linker relaxation might change offsets in the code, the DWARF special ++ opcodes and variable-length operands cannot be used. If this macro is ++ nonzero, use the DW_LNS_fixed_advance_pc opcode instead. */ ++#ifndef DWARF2_USE_FIXED_ADVANCE_PC ++# define DWARF2_USE_FIXED_ADVANCE_PC 0 ++#endif ++ ++/* First special line opcde - leave room for the standard opcodes. ++ Note: If you want to change this, you'll have to update the ++ "standard_opcode_lengths" table that is emitted below in ++ out_debug_line(). */ ++#define DWARF2_LINE_OPCODE_BASE 13 ++ ++#ifndef DWARF2_LINE_BASE ++ /* Minimum line offset in a special line info. opcode. This value ++ was chosen to give a reasonable range of values. */ ++# define DWARF2_LINE_BASE -5 ++#endif ++ ++/* Range of line offsets in a special line info. opcode. */ ++#ifndef DWARF2_LINE_RANGE ++# define DWARF2_LINE_RANGE 14 ++#endif ++ ++#ifndef DWARF2_LINE_MIN_INSN_LENGTH ++ /* Define the architecture-dependent minimum instruction length (in ++ bytes). This value should be rather too small than too big. */ ++# define DWARF2_LINE_MIN_INSN_LENGTH 1 ++#endif ++ ++/* Flag that indicates the initial value of the is_stmt_start flag. */ ++#define DWARF2_LINE_DEFAULT_IS_STMT 1 ++ ++/* Given a special op, return the line skip amount. */ ++#define SPECIAL_LINE(op) \ ++ (((op) - DWARF2_LINE_OPCODE_BASE)%DWARF2_LINE_RANGE + DWARF2_LINE_BASE) ++ ++/* Given a special op, return the address skip amount (in units of ++ DWARF2_LINE_MIN_INSN_LENGTH. */ ++#define SPECIAL_ADDR(op) (((op) - DWARF2_LINE_OPCODE_BASE)/DWARF2_LINE_RANGE) ++ ++/* The maximum address skip amount that can be encoded with a special op. */ ++#define MAX_SPECIAL_ADDR_DELTA SPECIAL_ADDR(255) ++ ++struct line_entry { ++ struct line_entry *next; ++ symbolS *label; ++ struct dwarf2_line_info loc; ++}; ++ ++struct line_subseg { ++ struct line_subseg *next; ++ subsegT subseg; ++ struct line_entry *head; ++ struct line_entry **ptail; ++}; ++ ++struct line_seg { ++ struct line_seg *next; ++ segT seg; ++ struct line_subseg *head; ++ symbolS *text_start; ++ symbolS *text_end; ++}; ++ ++/* Collects data for all line table entries during assembly. */ ++static struct line_seg *all_segs; ++ ++struct file_entry { ++ char *filename; ++ unsigned int dir; ++}; ++ ++/* Table of files used by .debug_line. */ ++static struct file_entry *files; ++static unsigned int files_in_use; ++static unsigned int files_allocated; ++ ++/* Table of directories used by .debug_line. */ ++static char **dirs; ++static unsigned int dirs_in_use; ++static unsigned int dirs_allocated; ++ ++/* TRUE when we've seen a .loc directive recently. Used to avoid ++ doing work when there's nothing to do. */ ++static bfd_boolean loc_directive_seen; ++ ++/* TRUE when we're supposed to set the basic block mark whenever a ++ label is seen. */ ++bfd_boolean dwarf2_loc_mark_labels; ++ ++/* Current location as indicated by the most recent .loc directive. */ ++static struct dwarf2_line_info current = { ++ 1, 1, 0, 0, ++ DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0 ++}; ++ ++/* When creating dwarf2 debugging information for assembly files, the --gdwarf2 ++ flag is specified, the variable dwarf2_file_number is used to generate a ++ .file for each assembly source file in read_a_source_file(). */ ++uint32_t dwarf2_file_number = 0; ++ ++/* Info gathered where creating dwarf2 debugging information for assembly files ++ when --gdwarf2 is specified. This is done in make_subprogram_for_symbol() ++ in symbols.c . */ ++struct dwarf2_subprogram_info *dwarf2_subprograms_info = NULL; ++ ++/* The size of an address on the target. */ ++static unsigned int sizeof_address; ++ ++static struct line_subseg *get_line_subseg (segT, subsegT); ++static unsigned int get_filenum (char *, unsigned int); ++static struct frag *first_frag_for_seg (segT); ++static struct frag *last_frag_for_seg (segT); ++static void out_byte (int); ++static void out_opcode (int); ++static void out_two (int); ++static void out_four (int); ++static void out_abbrev (int, int); ++static void out_uleb128 (addressT); ++static void out_sleb128 (addressT); ++static offsetT get_frag_fix (fragS *, segT); ++static void out_set_addr (symbolS *); ++static int size_inc_line_addr (int, addressT); ++static void emit_inc_line_addr (int, addressT, char *, int); ++static void out_inc_line_addr (int, addressT); ++static void out_fixed_inc_line_addr (int, symbolS *, symbolS *); ++static void relax_inc_line_addr (int, symbolS *, symbolS *); ++static int process_entries (segT, struct line_entry *); ++static void out_file_list (void); ++static void out_debug_line (struct frchain *); ++static void out_debug_aranges (struct frchain *, struct frchain *); ++static void out_debug_abbrev (struct frchain *); ++ ++/* ++ * This version of emit_expr() was based on the one in GAS's read.c but greatly ++ * simplified for the ported specific uses in here and the Mach-O version of the ++ * expression stuct. As such this looks at the X_seg field (aka X_op) and only ++ * deals with the expressions which have "type's" of SEG_SECT (aka O_symbol), ++ * and SEG_DIFFSECT. ++ * ++ * The function of this routine is to: ++ * Put the contents of expression EXP into the object file using ++ * NBYTES bytes. ++ */ ++static ++void ++emit_expr (expressionS *exp, unsigned int nbytes) ++{ ++ segT X_seg; ++ char *p; ++ ++ X_seg = exp->X_seg; ++ if(X_seg != SEG_SECT && X_seg != SEG_DIFFSECT) ++ as_fatal("internal error, emit_expr() called with unexpected expression " ++ "type"); ++ ++ p = frag_more ((int) nbytes); ++ ++ fix_new(frag_now, ++ p - frag_now->fr_literal, ++ nbytes, ++ exp->X_add_symbol, ++ exp->X_subtract_symbol, ++ exp->X_add_number, ++ 0, ++ 0, ++ 0); ++} ++ ++#define TC_DWARF2_EMIT_OFFSET macho_dwarf2_emit_offset ++static void ++macho_dwarf2_emit_offset (symbolS *symbol, unsigned int size); ++ ++#ifndef TC_DWARF2_EMIT_OFFSET ++#define TC_DWARF2_EMIT_OFFSET generic_dwarf2_emit_offset ++ ++/* Create an offset to .dwarf2_*. */ ++ ++static void ++generic_dwarf2_emit_offset (symbolS *symbol, unsigned int size) ++{ ++ expressionS expr; ++ ++ memset(&expr, '\0', sizeof(expr)); ++ expr.X_op = O_symbol; ++ expr.X_add_symbol = symbol; ++ expr.X_add_number = 0; ++ emit_expr (&expr, size); ++} ++#endif ++ ++/* Find or create an entry for SEG+SUBSEG in ALL_SEGS. */ ++ ++static struct line_subseg * ++get_line_subseg (segT seg, subsegT subseg) ++{ ++ static segT last_seg; ++ static subsegT last_subseg; ++ static struct line_subseg *last_line_subseg; ++ ++ struct line_seg **ps, *s; ++ struct line_subseg **pss, *ss; ++ ++ if (seg == last_seg && subseg == last_subseg) ++ return last_line_subseg; ++ ++ for (ps = &all_segs; (s = *ps) != NULL; ps = &s->next) ++ if (s->seg == seg) ++ goto found_seg; ++ ++ s = (struct line_seg *) xmalloc (sizeof (*s)); ++ s->next = NULL; ++ s->seg = seg; ++ s->head = NULL; ++ *ps = s; ++ ++ found_seg: ++ for (pss = &s->head; (ss = *pss) != NULL ; pss = &ss->next) ++ { ++ if (ss->subseg == subseg) ++ goto found_subseg; ++ if (ss->subseg > subseg) ++ break; ++ } ++ ++ ss = (struct line_subseg *) xmalloc (sizeof (*ss)); ++ ss->next = *pss; ++ ss->subseg = subseg; ++ ss->head = NULL; ++ ss->ptail = &ss->head; ++ *pss = ss; ++ ++ found_subseg: ++ last_seg = seg; ++ last_subseg = subseg; ++ last_line_subseg = ss; ++ ++ return ss; ++} ++ ++/* Record an entry for LOC occurring at LABEL. */ ++ ++static void ++dwarf2_gen_line_info_1 (symbolS *label, struct dwarf2_line_info *loc) ++{ ++ struct line_subseg *ss; ++ struct line_entry *e; ++ ++ e = (struct line_entry *) xmalloc (sizeof (*e)); ++ e->next = NULL; ++ e->label = label; ++ e->loc = *loc; ++ ++ ss = get_line_subseg (now_seg, now_subseg); ++ *ss->ptail = e; ++ ss->ptail = &e->next; ++} ++ ++/* Record an entry for LOC occurring at OFS within the current fragment. */ ++ ++void ++dwarf2_gen_line_info (addressT ofs, struct dwarf2_line_info *loc) ++{ ++ static unsigned int line = -1; ++ static unsigned int filenum = -1; ++ ++ symbolS *sym; ++ ++ /* Early out for as-yet incomplete location information. */ ++ if (loc->filenum == 0 || loc->line == 0) ++ return; ++ ++ /* Don't emit sequences of line symbols for the same line when the ++ symbols apply to assembler code. It is necessary to emit ++ duplicate line symbols when a compiler asks for them, because GDB ++ uses them to determine the end of the prologue. */ ++ if (debug_type == DEBUG_DWARF2 ++ && line == loc->line && filenum == loc->filenum) ++ return; ++ ++ line = loc->line; ++ filenum = loc->filenum; ++ ++ sym = symbol_temp_new (now_seg, ofs, frag_now); ++ dwarf2_gen_line_info_1 (sym, loc); ++} ++ ++/* Returns the current source information. If .file directives have ++ been encountered, the info for the corresponding source file is ++ returned. Otherwise, the info for the assembly source file is ++ returned. */ ++ ++void ++dwarf2_where (struct dwarf2_line_info *line) ++{ ++ if (debug_type == DEBUG_DWARF2) ++ { ++ char *filename; ++#ifdef OLD ++ as_where (&filename, &line->line); ++#else ++ as_file_and_line(&filename, &line->line); ++#endif ++ line->filenum = get_filenum (filename, 0); ++ line->column = 0; ++ line->flags = DWARF2_FLAG_IS_STMT; ++ line->isa = current.isa; ++ } ++ else ++ *line = current; ++} ++ ++/* A hook to allow the target backend to inform the line number state ++ machine of isa changes when assembler debug info is enabled. */ ++ ++void ++dwarf2_set_isa (unsigned int isa) ++{ ++ current.isa = isa; ++} ++ ++/* Called for each machine instruction, or relatively atomic group of ++ machine instructions (ie built-in macro). The instruction or group ++ is SIZE bytes in length. If dwarf2 line number generation is called ++ for, emit a line statement appropriately. */ ++ ++void ++dwarf2_emit_insn (int size) ++{ ++ struct dwarf2_line_info loc; ++ ++ if (loc_directive_seen) ++ { ++ /* Use the last location established by a .loc directive, not ++ the value returned by dwarf2_where(). That calls as_where() ++ which will return either the logical input file name (foo.c) ++ or the physical input file name (foo.s) and not the file name ++ specified in the most recent .loc directive (eg foo.h). */ ++ loc = current; ++ ++ /* Unless we generate DWARF2 debugging information for each ++ assembler line, we only emit one line symbol for one LOC. */ ++ if (debug_type != DEBUG_DWARF2) ++ loc_directive_seen = FALSE; ++ } ++ else if (debug_type != DEBUG_DWARF2 || frchain_now->frch_nsect != text_nsect) ++ return; ++ else ++ dwarf2_where (&loc); ++ ++ dwarf2_gen_line_info (frag_now_fix () - size, &loc); ++ ++ current.flags &= ~(DWARF2_FLAG_BASIC_BLOCK ++ | DWARF2_FLAG_PROLOGUE_END ++ | DWARF2_FLAG_EPILOGUE_BEGIN); ++} ++ ++/* Called for each (preferably code) label. If dwarf2_loc_mark_labels ++ is enabled, emit a basic block marker. */ ++ ++void ++dwarf2_emit_label (symbolS *label) ++{ ++ struct dwarf2_line_info loc; ++ ++ if (!dwarf2_loc_mark_labels) ++ return; ++#ifdef OLD ++ if (S_GET_SEGMENT (label) != now_seg) ++#else ++ if (label->sy_nlist.n_sect != now_seg) ++#endif ++ return; ++#ifdef OLD ++ if (!(bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE)) ++#else ++ if ((get_section_by_nsect(now_seg)->frch_section.flags & ++ S_ATTR_SOME_INSTRUCTIONS) == 0) ++#endif ++ return; ++ ++ if (debug_type == DEBUG_DWARF2) ++ dwarf2_where (&loc); ++ else ++ { ++ loc = current; ++ loc_directive_seen = FALSE; ++ } ++ ++ loc.flags |= DWARF2_FLAG_BASIC_BLOCK; ++ ++ current.flags &= ~(DWARF2_FLAG_BASIC_BLOCK ++ | DWARF2_FLAG_PROLOGUE_END ++ | DWARF2_FLAG_EPILOGUE_BEGIN); ++ ++ dwarf2_gen_line_info_1 (label, &loc); ++} ++ ++#ifndef OLD ++/* ++ * Internal lbasename() routine that must be used in this code. As it returns ++ * a pointer into the path as get_filenum() expects for the base name of the ++ * path. ++ */ ++static ++char * ++lbasename( ++char *path) ++{ ++ char *p; ++ ++ p = strrchr(path, '/'); ++ if(p != NULL) ++ return(p + 1); ++ else ++ return(path); ++} ++#endif /* !defined(OLD) */ ++ ++/* Get a .debug_line file number for FILENAME. If NUM is nonzero, ++ allocate it on that file table slot, otherwise return the first ++ empty one. */ ++ ++static unsigned int ++get_filenum (char *filename, unsigned int num) ++{ ++ static unsigned int last_used, last_used_dir_len; ++ char *file; ++ size_t dir_len; ++ unsigned int i, dir; ++ ++ if (num == 0 && last_used) ++ { ++ if (! files[last_used].dir ++ && strcmp (filename, files[last_used].filename) == 0) ++ return last_used; ++ if (files[last_used].dir ++ && strncmp (filename, dirs[files[last_used].dir], ++ last_used_dir_len) == 0 ++ && IS_DIR_SEPARATOR (filename [last_used_dir_len]) ++ && strcmp (filename + last_used_dir_len + 1, ++ files[last_used].filename) == 0) ++ return last_used; ++ } ++ ++ file = lbasename (filename); ++ /* Don't make empty string from / or A: from A:/ . */ ++#ifdef HAVE_DOS_BASED_FILE_SYSTEM ++ if (file <= filename + 3) ++ file = filename; ++#else ++ if (file == filename + 1) ++ file = filename; ++#endif ++ dir_len = file - filename; ++ ++ dir = 0; ++ if (dir_len) ++ { ++ --dir_len; ++ for (dir = 1; dir < dirs_in_use; ++dir) ++ if (strncmp (filename, dirs[dir], dir_len) == 0 ++ && dirs[dir][dir_len] == '\0') ++ break; ++ ++ if (dir >= dirs_in_use) ++ { ++ if (dir >= dirs_allocated) ++ { ++ dirs_allocated = dir + 32; ++ dirs = (char **) ++ xrealloc (dirs, (dir + 32) * sizeof (const char *)); ++ } ++ ++ dirs[dir] = xmalloc (dir_len + 1); ++ memcpy (dirs[dir], filename, dir_len); ++ dirs[dir][dir_len] = '\0'; ++ dirs_in_use = dir + 1; ++ } ++ } ++ ++ if (num == 0) ++ { ++ for (i = 1; i < files_in_use; ++i) ++ if (files[i].dir == dir ++ && files[i].filename ++ && strcmp (file, files[i].filename) == 0) ++ { ++ last_used = i; ++ last_used_dir_len = dir_len; ++ return i; ++ } ++ } ++ else ++ i = num; ++ ++ if (i >= files_allocated) ++ { ++ unsigned int old = files_allocated; ++ ++ files_allocated = i + 32; ++ files = (struct file_entry *) ++ xrealloc (files, (i + 32) * sizeof (struct file_entry)); ++ ++ memset (files + old, 0, (i + 32 - old) * sizeof (struct file_entry)); ++ } ++ ++#ifdef OLD ++ files[i].filename = num ? file : xstrdup (file); ++#else ++ if(num == 0) ++ files[i].filename = file; ++ else ++ { ++ files[i].filename = xmalloc(strlen(file) + 1); ++ strcpy(files[i].filename, file); ++ } ++#endif ++ files[i].dir = dir; ++ if (files_in_use < i + 1) ++ files_in_use = i + 1; ++ last_used = i; ++ last_used_dir_len = dir_len; ++ ++ return i; ++} ++ ++/* Handle two forms of .file directive: ++ - Pass .file "source.c" to s_app_file ++ - Handle .file 1 "source.c" by adding an entry to the DWARF-2 file table ++ ++ If an entry is added to the file table, return a pointer to the filename. */ ++ ++char * ++dwarf2_directive_file (uintptr_t dummy ATTRIBUTE_UNUSED) ++{ ++ offsetT num; ++ char *filename; ++ int filename_len; ++ ++ /* Continue to accept a bare string and pass it off. */ ++ SKIP_WHITESPACE (); ++ if (*input_line_pointer == '"') ++ { ++ s_app_file (0); ++ return NULL; ++ } ++ ++ num = get_absolute_expression (); ++ filename = demand_copy_C_string (&filename_len); ++ if (filename == NULL) ++ return NULL; ++ demand_empty_rest_of_line (); ++ ++ /* ++ * If the --gdwarf2 flag is present to generate dwarf2 for assembly code ++ * then it is an error to see a .file directive in the source. ++ */ ++ if (debug_type == DEBUG_DWARF2) ++ { ++ as_bad (_("input can't have .file dwarf directives when -g is used to " ++ "generate dwarf debug info for assembly code")); ++ return NULL; ++ } ++ ++ if (num < 1) ++ { ++ as_bad (_("file number less than one")); ++ return NULL; ++ } ++ ++ if (num < (int) files_in_use && files[num].filename != 0) ++ { ++ as_bad (_("file number %ld already allocated"), (long) num); ++ return NULL; ++ } ++ ++ get_filenum (filename, num); ++ ++ return filename; ++} ++ ++/* ++ * Same functionality as above but this is used when generating dwarf debugging ++ * info for assembly files with --gdwarf2. ++ */ ++void ++dwarf2_file ( ++char *filename, ++offsetT num) ++{ ++ get_filenum (filename, num); ++} ++ ++void ++dwarf2_directive_loc (uintptr_t dummy ATTRIBUTE_UNUSED) ++{ ++ offsetT filenum, line; ++ ++ filenum = get_absolute_expression (); ++ SKIP_WHITESPACE (); ++ line = get_absolute_expression (); ++ ++ if (filenum < 1) ++ { ++ as_bad (_("file number less than one")); ++ return; ++ } ++ if (filenum >= (int) files_in_use || files[filenum].filename == 0) ++ { ++ as_bad (_("unassigned file number %ld"), (long) filenum); ++ return; ++ } ++ ++ current.filenum = filenum; ++ current.line = line; ++ ++#ifndef NO_LISTING ++ if (listing) ++ { ++ if (files[filenum].dir) ++ { ++ size_t dir_len = strlen (dirs[files[filenum].dir]); ++ size_t file_len = strlen (files[filenum].filename); ++ char *cp = (char *) alloca (dir_len + 1 + file_len + 1); ++ ++ memcpy (cp, dirs[files[filenum].dir], dir_len); ++ INSERT_DIR_SEPARATOR (cp, dir_len); ++ memcpy (cp + dir_len + 1, files[filenum].filename, file_len); ++ cp[dir_len + file_len + 1] = '\0'; ++ listing_source_file (cp); ++ } ++ else ++ listing_source_file (files[filenum].filename); ++ listing_source_line (line); ++ } ++#endif ++ ++ SKIP_WHITESPACE (); ++ if (ISDIGIT (*input_line_pointer)) ++ { ++ current.column = get_absolute_expression (); ++ SKIP_WHITESPACE (); ++ } ++ ++ while (ISALPHA (*input_line_pointer)) ++ { ++ char *p, c; ++ offsetT value; ++ ++ p = input_line_pointer; ++ c = get_symbol_end (); ++ ++ if (strcmp (p, "basic_block") == 0) ++ { ++ current.flags |= DWARF2_FLAG_BASIC_BLOCK; ++ *input_line_pointer = c; ++ } ++ else if (strcmp (p, "prologue_end") == 0) ++ { ++ current.flags |= DWARF2_FLAG_PROLOGUE_END; ++ *input_line_pointer = c; ++ } ++ else if (strcmp (p, "epilogue_begin") == 0) ++ { ++ current.flags |= DWARF2_FLAG_EPILOGUE_BEGIN; ++ *input_line_pointer = c; ++ } ++ else if (strcmp (p, "is_stmt") == 0) ++ { ++ *input_line_pointer = c; ++ value = get_absolute_expression (); ++ if (value == 0) ++ current.flags &= ~DWARF2_FLAG_IS_STMT; ++ else if (value == 1) ++ current.flags |= DWARF2_FLAG_IS_STMT; ++ else ++ { ++ as_bad (_("is_stmt value not 0 or 1")); ++ return; ++ } ++ } ++ else if (strcmp (p, "isa") == 0) ++ { ++ *input_line_pointer = c; ++ value = get_absolute_expression (); ++ if (value >= 0) ++ current.isa = value; ++ else ++ { ++ as_bad (_("isa number less than zero")); ++ return; ++ } ++ } ++ else ++ { ++ as_bad (_("unknown .loc sub-directive `%s'"), p); ++ *input_line_pointer = c; ++ return; ++ } ++ ++ SKIP_WHITESPACE (); ++ } ++ ++ demand_empty_rest_of_line (); ++ loc_directive_seen = TRUE; ++} ++ ++/* ++ * Same functionality as above but this is used when generating dwarf debugging ++ * info for assembly files with --gdwarf2. ++ */ ++void ++dwarf2_loc (offsetT filenum, offsetT line) ++{ ++ current.filenum = filenum; ++ current.line = line; ++} ++ ++void ++dwarf2_directive_loc_mark_labels (uintptr_t dummy ATTRIBUTE_UNUSED) ++{ ++ offsetT value = get_absolute_expression (); ++ ++ if (value != 0 && value != 1) ++ { ++ as_bad (_("expected 0 or 1")); ++ ignore_rest_of_line (); ++ } ++ else ++ { ++ dwarf2_loc_mark_labels = value != 0; ++ demand_empty_rest_of_line (); ++ } ++} ++ ++static struct frag * ++first_frag_for_seg (segT seg) ++{ ++ return get_section_by_nsect(seg)->frch_root; ++} ++ ++static struct frag * ++last_frag_for_seg (segT seg) ++{ ++ frchainS *f = get_section_by_nsect(seg); ++ ++#ifdef OLD ++ while (f->frch_next != NULL) ++ f = f->frch_next; ++#endif ++ ++ return f->frch_last; ++} ++ ++/* Emit a single byte into the current segment. */ ++ ++static inline void ++out_byte (int byte) ++{ ++ FRAG_APPEND_1_CHAR (byte); ++} ++ ++/* Emit a statement program opcode into the current segment. */ ++ ++static inline void ++out_opcode (int opc) ++{ ++ out_byte (opc); ++} ++ ++/* Emit a two-byte word into the current segment. */ ++ ++static inline void ++out_two (int data) ++{ ++ md_number_to_chars (frag_more (2), data, 2); ++} ++ ++/* Emit a four byte word into the current segment. */ ++ ++static inline void ++out_four (int data) ++{ ++ md_number_to_chars (frag_more (4), data, 4); ++} ++ ++/* Emit an unsigned "little-endian base 128" number. */ ++ ++static void ++out_uleb128 (addressT value) ++{ ++ output_leb128 (frag_more (sizeof_leb128 (value, 0)), value, 0); ++} ++ ++/* Emit a signed "little-endian base 128" number. */ ++ ++static void ++out_sleb128 (addressT value) ++{ ++ output_leb128 (frag_more (sizeof_leb128 (value, 1)), value, 1); ++} ++ ++/* Emit a tuple for .debug_abbrev. */ ++ ++static inline void ++out_abbrev (int name, int form) ++{ ++ out_uleb128 (name); ++ out_uleb128 (form); ++} ++ ++/* Get the size of a fragment. */ ++ ++static offsetT ++get_frag_fix (fragS *frag, segT seg) ++{ ++#ifdef OLD ++#endif ++ frchainS *fr; ++ ++ if (frag->fr_next) ++ return frag->fr_fix; ++ ++ /* If a fragment is the last in the chain, special measures must be ++ taken to find its size before relaxation, since it may be pending ++ on some subsegment chain. */ ++ for (fr = get_section_by_nsect(seg); fr; fr = fr->frch_next) ++ if (fr->frch_last == frag) { ++#ifdef OLD ++ return (char *) obstack_next_free (&frags /* was &fr->frch_obstack */) - frag->fr_literal; ++ ++ abort (); ++#else ++ /* This depends on add_last_frags_to_sections() being called to make ++ sure the last frag in a section is a ".fill 0". Since in the Mach-O ++ assembler we don't have an obstack per section using the above ++ code to subtract the frag's fr_literal from what ever was the last ++ frag allocated will not work. */ ++ return(0); ++#endif ++ } ++ as_fatal("internal error, did not find frag in section in " ++ "get_frag_fix()"); ++ return(0); /* not reached, but here remove compiler warning */ ++} ++ ++/* Set an absolute address (may result in a relocation entry). */ ++ ++static void ++out_set_addr (symbolS *sym) ++{ ++ expressionS expr; ++ ++ out_opcode (DW_LNS_extended_op); ++ out_uleb128 (sizeof_address + 1); ++ ++ out_opcode (DW_LNE_set_address); ++ memset(&expr, '\0', sizeof(expr)); ++ expr.X_op = O_symbol; ++ expr.X_add_symbol = sym; ++ expr.X_add_number = 0; ++ emit_expr (&expr, sizeof_address); ++} ++ ++#if DWARF2_LINE_MIN_INSN_LENGTH > 1 ++static void scale_addr_delta (addressT *); ++ ++static void ++scale_addr_delta (addressT *addr_delta) ++{ ++ static int printed_this = 0; ++ if (*addr_delta % DWARF2_LINE_MIN_INSN_LENGTH != 0) ++ { ++ if (!printed_this) ++ as_bad("unaligned opcodes detected in executable segment"); ++ printed_this = 1; ++ } ++ *addr_delta /= DWARF2_LINE_MIN_INSN_LENGTH; ++} ++#else ++#define scale_addr_delta(A) ++#endif ++ ++/* Encode a pair of line and address skips as efficiently as possible. ++ Note that the line skip is signed, whereas the address skip is unsigned. ++ ++ The following two routines *must* be kept in sync. This is ++ enforced by making emit_inc_line_addr abort if we do not emit ++ exactly the expected number of bytes. */ ++ ++static int ++size_inc_line_addr (int line_delta, addressT addr_delta) ++{ ++ unsigned int tmp, opcode; ++ int len = 0; ++ ++ /* Scale the address delta by the minimum instruction length. */ ++ scale_addr_delta (&addr_delta); ++ ++ /* INT_MAX is a signal that this is actually a DW_LNE_end_sequence. ++ We cannot use special opcodes here, since we want the end_sequence ++ to emit the matrix entry. */ ++ if (line_delta == INT_MAX) ++ { ++ if (addr_delta == MAX_SPECIAL_ADDR_DELTA) ++ len = 1; ++ else ++ len = 1 + sizeof_leb128 (addr_delta, 0); ++ return len + 3; ++ } ++ ++ /* Bias the line delta by the base. */ ++ tmp = line_delta - DWARF2_LINE_BASE; ++ ++ /* If the line increment is out of range of a special opcode, we ++ must encode it with DW_LNS_advance_line. */ ++ if (tmp >= DWARF2_LINE_RANGE) ++ { ++ len = 1 + sizeof_leb128 (line_delta, 1); ++ line_delta = 0; ++ tmp = 0 - DWARF2_LINE_BASE; ++ } ++ ++ /* Bias the opcode by the special opcode base. */ ++ tmp += DWARF2_LINE_OPCODE_BASE; ++ ++ /* Avoid overflow when addr_delta is large. */ ++ if (addr_delta < 256 + MAX_SPECIAL_ADDR_DELTA) ++ { ++ /* Try using a special opcode. */ ++ opcode = tmp + addr_delta * DWARF2_LINE_RANGE; ++ if (opcode <= 255) ++ return len + 1; ++ ++ /* Try using DW_LNS_const_add_pc followed by special op. */ ++ opcode = tmp + (addr_delta - MAX_SPECIAL_ADDR_DELTA) * DWARF2_LINE_RANGE; ++ if (opcode <= 255) ++ return len + 2; ++ } ++ ++ /* Otherwise use DW_LNS_advance_pc. */ ++ len += 1 + sizeof_leb128 (addr_delta, 0); ++ ++ /* DW_LNS_copy or special opcode. */ ++ len += 1; ++ ++ return len; ++} ++ ++static void ++emit_inc_line_addr (int line_delta, addressT addr_delta, char *p, int len) ++{ ++ unsigned int tmp, opcode; ++ int need_copy = 0; ++ char *end = p + len; ++ ++ /* Line number sequences cannot go backward in addresses. This means ++ we've incorrectly ordered the statements in the sequence. */ ++ assert ((offsetT) addr_delta >= 0); ++ ++ /* Scale the address delta by the minimum instruction length. */ ++ scale_addr_delta (&addr_delta); ++ ++ /* INT_MAX is a signal that this is actually a DW_LNE_end_sequence. ++ We cannot use special opcodes here, since we want the end_sequence ++ to emit the matrix entry. */ ++ if (line_delta == INT_MAX) ++ { ++ if (addr_delta == MAX_SPECIAL_ADDR_DELTA) ++ *p++ = DW_LNS_const_add_pc; ++ else ++ { ++ *p++ = DW_LNS_advance_pc; ++ p += output_leb128 (p, addr_delta, 0); ++ } ++ ++ *p++ = DW_LNS_extended_op; ++ *p++ = 1; ++ *p++ = DW_LNE_end_sequence; ++ goto done; ++ } ++ ++ /* Bias the line delta by the base. */ ++ tmp = line_delta - DWARF2_LINE_BASE; ++ ++ /* If the line increment is out of range of a special opcode, we ++ must encode it with DW_LNS_advance_line. */ ++ if (tmp >= DWARF2_LINE_RANGE) ++ { ++ *p++ = DW_LNS_advance_line; ++ p += output_leb128 (p, line_delta, 1); ++ ++ line_delta = 0; ++ tmp = 0 - DWARF2_LINE_BASE; ++ need_copy = 1; ++ } ++ ++ /* Prettier, I think, to use DW_LNS_copy instead of a "line +0, addr +0" ++ special opcode. */ ++ if (line_delta == 0 && addr_delta == 0) ++ { ++ *p++ = DW_LNS_copy; ++ goto done; ++ } ++ ++ /* Bias the opcode by the special opcode base. */ ++ tmp += DWARF2_LINE_OPCODE_BASE; ++ ++ /* Avoid overflow when addr_delta is large. */ ++ if (addr_delta < 256 + MAX_SPECIAL_ADDR_DELTA) ++ { ++ /* Try using a special opcode. */ ++ opcode = tmp + addr_delta * DWARF2_LINE_RANGE; ++ if (opcode <= 255) ++ { ++ *p++ = opcode; ++ goto done; ++ } ++ ++ /* Try using DW_LNS_const_add_pc followed by special op. */ ++ opcode = tmp + (addr_delta - MAX_SPECIAL_ADDR_DELTA) * DWARF2_LINE_RANGE; ++ if (opcode <= 255) ++ { ++ *p++ = DW_LNS_const_add_pc; ++ *p++ = opcode; ++ goto done; ++ } ++ } ++ ++ /* Otherwise use DW_LNS_advance_pc. */ ++ *p++ = DW_LNS_advance_pc; ++ p += output_leb128 (p, addr_delta, 0); ++ ++ if (need_copy) ++ *p++ = DW_LNS_copy; ++ else ++ *p++ = tmp; ++ ++ done: ++ if (p != end) ++ as_fatal("internal error, p != end at the end of emit_inc_line_addr()"); ++} ++ ++/* Handy routine to combine calls to the above two routines. */ ++ ++static void ++out_inc_line_addr (int line_delta, addressT addr_delta) ++{ ++ int len = size_inc_line_addr (line_delta, addr_delta); ++ emit_inc_line_addr (line_delta, addr_delta, frag_more (len), len); ++} ++ ++/* Write out an alternative form of line and address skips using ++ DW_LNS_fixed_advance_pc opcodes. This uses more space than the default ++ line and address information, but it helps support linker relaxation that ++ changes the code offsets. */ ++ ++static void ++out_fixed_inc_line_addr (int line_delta, symbolS *to_sym, symbolS *from_sym) ++{ ++ expressionS expr; ++ ++ /* INT_MAX is a signal that this is actually a DW_LNE_end_sequence. */ ++ if (line_delta == INT_MAX) ++ { ++ out_opcode (DW_LNS_fixed_advance_pc); ++ memset(&expr, '\0', sizeof(expr)); ++#ifdef OLD ++ expr.X_op = O_subtract; ++#else ++ expr.X_seg = SEG_DIFFSECT; ++#endif ++ expr.X_add_symbol = to_sym; ++#ifdef OLD ++ expr.X_op_symbol = from_sym; ++#else ++ expr.X_subtract_symbol = from_sym; ++#endif ++ expr.X_add_number = 0; ++ emit_expr (&expr, 2); ++ ++ out_opcode (DW_LNS_extended_op); ++ out_byte (1); ++ out_opcode (DW_LNE_end_sequence); ++ return; ++ } ++ ++ out_opcode (DW_LNS_advance_line); ++ out_sleb128 (line_delta); ++ ++ out_opcode (DW_LNS_fixed_advance_pc); ++ memset(&expr, '\0', sizeof(expr)); ++#ifdef OLD ++ expr.X_op = O_subtract; ++#else ++ expr.X_seg = SEG_DIFFSECT; ++#endif ++ expr.X_add_symbol = to_sym; ++#ifdef OLD ++ expr.X_op_symbol = from_sym; ++#else ++ expr.X_subtract_symbol = from_sym; ++#endif ++ expr.X_add_number = 0; ++ emit_expr (&expr, 2); ++ ++ out_opcode (DW_LNS_copy); ++} ++ ++/* Generate a variant frag that we can use to relax address/line ++ increments between fragments of the target segment. */ ++ ++static void ++relax_inc_line_addr (int line_delta, symbolS *to_sym, symbolS *from_sym) ++{ ++ int max_chars; ++#ifdef OLD ++ expressionS expr; ++#else ++ symbolS *sym; ++ expressionS *expression; ++ ++ sym = symbol_temp_new(to_sym->sy_other, 0, NULL); ++ expression = xmalloc(sizeof(expressionS)); ++ memset(expression, '\0', sizeof(expressionS)); ++ sym->expression = expression; ++ sym->sy_frag = &zero_address_frag; ++#endif ++ ++#ifdef OLD ++ expr.X_op = O_subtract; ++ expr.X_add_symbol = to_sym; ++ expr.X_op_symbol = from_sym; ++ expr.X_add_number = 0; ++#else ++ expression->X_seg = SEG_DIFFSECT; ++ expression->X_add_symbol = to_sym; ++ expression->X_subtract_symbol = from_sym; ++ expression->X_add_number = 0; ++#endif ++ ++ /* The maximum size of the frag is the line delta with a maximum ++ sized address delta. */ ++ max_chars = size_inc_line_addr (line_delta, -DWARF2_LINE_MIN_INSN_LENGTH); ++ ++#ifdef OLD ++ frag_var (rs_dwarf2dbg, max_chars, max_chars, 1, ++ make_expr_symbol (&expr), line_delta, NULL); ++#else ++ frag_var (rs_dwarf2dbg, max_chars, max_chars, 1, ++ sym, line_delta, NULL); ++#endif ++} ++ ++ ++/* The function estimates the size of a rs_dwarf2dbg variant frag ++ based on the current values of the symbols. It is called before ++ the relaxation loop. We set fr_subtype to the expected length. */ ++ ++int ++dwarf2dbg_estimate_size_before_relax (fragS *frag) ++{ ++ offsetT addr_delta; ++ int size; ++#ifndef OLD ++ expressionS *expression; ++#endif ++ ++#ifdef OLD ++ addr_delta = resolve_symbol_value (frag->fr_symbol); ++#else ++ if(frag->fr_symbol == NULL || frag->fr_symbol->expression == NULL) ++ as_bad("Internal error dwarf2dbg_estimate_size_before_relax() called with " ++ "frag without symbol or expression\n"); ++ ++ expression = (expressionS *)frag->fr_symbol->expression; ++ if(expression->X_seg != SEG_DIFFSECT || ++ expression->X_add_symbol == NULL || ++ expression->X_subtract_symbol == NULL) ++ as_bad("Internal error dwarf2dbg_estimate_size_before_relax() called with " ++ "frag symbol with bad expression\n"); ++ ++ addr_delta = (expression->X_add_symbol->sy_nlist.n_value + ++ expression->X_add_symbol->sy_frag->fr_address) ++ - (expression->X_subtract_symbol->sy_nlist.n_value + ++ expression->X_subtract_symbol->sy_frag->fr_address) ++ + expression->X_add_number; ++#endif ++ ++ size = size_inc_line_addr (frag->fr_offset, addr_delta); ++ ++ frag->fr_subtype = size; ++ ++ return size; ++} ++ ++/* This function relaxes a rs_dwarf2dbg variant frag based on the ++ current values of the symbols. fr_subtype is the current length ++ of the frag. This returns the change in frag length. */ ++ ++int ++dwarf2dbg_relax_frag (fragS *frag) ++{ ++ int old_size, new_size; ++ ++ old_size = frag->fr_subtype; ++ new_size = dwarf2dbg_estimate_size_before_relax (frag); ++ ++ return new_size - old_size; ++} ++ ++/* This function converts a rs_dwarf2dbg variant frag into a normal ++ fill frag. This is called after all relaxation has been done. ++ fr_subtype will be the desired length of the frag. */ ++ ++void ++dwarf2dbg_convert_frag (fragS *frag) ++{ ++ offsetT addr_diff; ++#ifndef OLD ++ expressionS *expression; ++#endif ++ ++#ifdef OLD ++ addr_diff = resolve_symbol_value (frag->fr_symbol); ++#else ++ if(frag->fr_symbol == NULL || frag->fr_symbol->expression == NULL) ++ as_bad("Internal error dwarf2dbg_convert_frag() called with " ++ "frag without symbol or expression\n"); ++ ++ expression = (expressionS *)frag->fr_symbol->expression; ++ if(expression->X_seg != SEG_DIFFSECT || ++ expression->X_add_symbol == NULL || ++ expression->X_subtract_symbol == NULL) ++ as_bad("Internal error dwarf2dbg_convert_frag() called with " ++ "frag symbol with bad expression\n"); ++ ++ addr_diff = expression->X_add_symbol->sy_nlist.n_value ++ - expression->X_subtract_symbol->sy_nlist.n_value ++ + expression->X_add_number; ++#endif ++ ++ /* fr_var carries the max_chars that we created the fragment with. ++ fr_subtype carries the current expected length. We must, of ++ course, have allocated enough memory earlier. */ ++ assert (frag->fr_var >= (int) frag->fr_subtype); ++ ++ emit_inc_line_addr (frag->fr_offset, addr_diff, ++ frag->fr_literal + frag->fr_fix, frag->fr_subtype); ++ ++ frag->fr_fix += frag->fr_subtype; ++ frag->fr_type = rs_fill; ++ frag->fr_var = 0; ++ frag->fr_offset = 0; ++} ++ ++/* Generate .debug_line content for the chain of line number entries ++ beginning at E, for segment SEG. */ ++ ++static int ++process_entries (segT seg, struct line_entry *e) ++{ ++ unsigned filenum = 1; ++ unsigned line = 1; ++ unsigned column = 0; ++ unsigned isa = 0; ++ unsigned flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; ++ fragS *last_frag = NULL, *frag; ++ addressT last_frag_ofs = 0, frag_ofs; ++ symbolS *last_lab = NULL, *lab; ++ struct line_entry *next; ++ int output_something = 0; ++ ++ do ++ { ++ int line_delta; ++ ++ if (filenum != e->loc.filenum) ++ { ++ filenum = e->loc.filenum; ++ out_opcode (DW_LNS_set_file); ++ out_uleb128 (filenum); ++ } ++ ++ if (column != e->loc.column) ++ { ++ column = e->loc.column; ++ out_opcode (DW_LNS_set_column); ++ out_uleb128 (column); ++ } ++ ++ if (isa != e->loc.isa) ++ { ++ isa = e->loc.isa; ++ out_opcode (DW_LNS_set_isa); ++ out_uleb128 (isa); ++ } ++ ++ if ((e->loc.flags ^ flags) & DWARF2_FLAG_IS_STMT) ++ { ++ flags = e->loc.flags; ++ out_opcode (DW_LNS_negate_stmt); ++ } ++ ++ if (e->loc.flags & DWARF2_FLAG_BASIC_BLOCK) ++ out_opcode (DW_LNS_set_basic_block); ++ ++ if (e->loc.flags & DWARF2_FLAG_PROLOGUE_END) ++ out_opcode (DW_LNS_set_prologue_end); ++ ++ if (e->loc.flags & DWARF2_FLAG_EPILOGUE_BEGIN) ++ out_opcode (DW_LNS_set_epilogue_begin); ++ ++ /* Don't try to optimize away redundant entries; gdb wants two ++ entries for a function where the code starts on the same line as ++ the open curly brace, and there's no way to identify that case here. ++ Trust gcc to optimize appropriately. */ ++ line_delta = e->loc.line - line; ++ lab = e->label; ++ frag = symbol_get_frag (lab); ++#ifdef OLD ++ frag_ofs = S_GET_VALUE (lab); ++#else ++ frag_ofs = lab->sy_nlist.n_value + frag->fr_address + frag->fr_offset; ++#endif ++ ++ if (last_frag == NULL) ++ { ++ out_set_addr (lab); ++ out_inc_line_addr (line_delta, 0); ++ } ++ else if (DWARF2_USE_FIXED_ADVANCE_PC) ++ out_fixed_inc_line_addr (line_delta, lab, last_lab); ++ else if (frag == last_frag) ++ out_inc_line_addr (line_delta, frag_ofs - last_frag_ofs); ++ else ++ relax_inc_line_addr (line_delta, lab, last_lab); ++ ++ line = e->loc.line; ++ last_lab = lab; ++ last_frag = frag; ++ last_frag_ofs = frag_ofs; ++ ++ next = e->next; ++ free (e); ++ e = next; ++ output_something = 1; ++ } ++ while (e); ++ ++ /* Emit a DW_LNE_end_sequence for the end of the section. */ ++ frag = last_frag_for_seg (seg); ++ frag_ofs = get_frag_fix (frag, seg); ++ if (DWARF2_USE_FIXED_ADVANCE_PC) ++ { ++ lab = symbol_temp_new (seg, frag_ofs, frag); ++ out_fixed_inc_line_addr (INT_MAX, lab, last_lab); ++ } ++ else if (frag == last_frag) ++ out_inc_line_addr (INT_MAX, frag_ofs - last_frag_ofs); ++ else ++ { ++ lab = symbol_temp_new (seg, frag_ofs, frag); ++ relax_inc_line_addr (INT_MAX, lab, last_lab); ++ } ++ ++ return (output_something); ++} ++ ++/* Emit the directory and file tables for .debug_line. */ ++ ++static void ++out_file_list (void) ++{ ++ size_t size; ++ char *cp; ++ unsigned int i; ++ ++ /* Emit directory list. */ ++ for (i = 1; i < dirs_in_use; ++i) ++ { ++ size = strlen (dirs[i]) + 1; ++ cp = frag_more (size); ++ memcpy (cp, dirs[i], size); ++ } ++ /* Terminate it. */ ++ out_byte ('\0'); ++ ++ for (i = 1; i < files_in_use; ++i) ++ { ++ if (files[i].filename == NULL) ++ { ++ as_bad (_("unassigned file number %ld"), (long) i); ++ /* Prevent a crash later, particularly for file 1. */ ++ files[i].filename = ""; ++ continue; ++ } ++ ++ size = strlen (files[i].filename) + 1; ++ cp = frag_more (size); ++ memcpy (cp, files[i].filename, size); ++ ++ out_uleb128 (files[i].dir); /* directory number */ ++ out_uleb128 (0); /* last modification timestamp */ ++ out_uleb128 (0); /* filesize */ ++ } ++ ++ /* Terminate filename list. */ ++ out_byte (0); ++} ++ ++/* Emit the collected .debug_line data. */ ++ ++static void ++out_debug_line( ++struct frchain *line_section) ++{ ++ expressionS expr; ++ symbolS *line_start; ++ symbolS *prologue_end; ++ symbolS *line_end; ++ struct line_seg *s; ++ enum dwarf2_format d2f; ++ int sizeof_offset, output_something; ++ ++ section_set(line_section); ++ ++ line_start = symbol_temp_new_now (); ++ prologue_end = symbol_temp_make (); ++ line_end = symbol_temp_make (); ++ ++ /* Total length of the information for this compilation unit. */ ++ memset(&expr, '\0', sizeof(expr)); ++#ifdef OLD ++ expr.X_op = O_subtract; ++#else ++ expr.X_seg = SEG_DIFFSECT; ++#endif ++ expr.X_add_symbol = line_end; ++#ifdef OLD ++ expr.X_op_symbol = line_start; ++#else ++ expr.X_subtract_symbol = line_start; ++#endif ++ ++ d2f = DWARF2_FORMAT (); ++ if (d2f == dwarf2_format_32bit) ++ { ++ expr.X_add_number = -4; ++ emit_expr (&expr, 4); ++ sizeof_offset = 4; ++ } ++ else if (d2f == dwarf2_format_64bit) ++ { ++ expr.X_add_number = -12; ++ out_four (-1); ++ emit_expr (&expr, 8); ++ sizeof_offset = 8; ++ } ++ else if (d2f == dwarf2_format_64bit_irix) ++ { ++ expr.X_add_number = -8; ++ emit_expr (&expr, 8); ++ sizeof_offset = 8; ++ } ++ else ++ { ++ as_fatal (_("internal error: unknown dwarf2 format")); ++ } ++ ++ /* Version. */ ++ out_two (2); ++ ++ memset(&expr, '\0', sizeof(expr)); ++ /* Length of the prologue following this length. */ ++#ifdef OLD ++ expr.X_op = O_subtract; ++#else ++ expr.X_seg = SEG_DIFFSECT; ++#endif ++ expr.X_add_symbol = prologue_end; ++#ifdef OLD ++ expr.X_op_symbol = line_start; ++#else ++ expr.X_subtract_symbol = line_start; ++#endif ++ expr.X_add_number = - (4 + 2 + 4); ++ emit_expr (&expr, sizeof_offset); ++ ++ /* Parameters of the state machine. */ ++ out_byte (DWARF2_LINE_MIN_INSN_LENGTH); ++ out_byte (DWARF2_LINE_DEFAULT_IS_STMT); ++ out_byte (DWARF2_LINE_BASE); ++ out_byte (DWARF2_LINE_RANGE); ++ out_byte (DWARF2_LINE_OPCODE_BASE); ++ ++ /* Standard opcode lengths. */ ++ out_byte (0); /* DW_LNS_copy */ ++ out_byte (1); /* DW_LNS_advance_pc */ ++ out_byte (1); /* DW_LNS_advance_line */ ++ out_byte (1); /* DW_LNS_set_file */ ++ out_byte (1); /* DW_LNS_set_column */ ++ out_byte (0); /* DW_LNS_negate_stmt */ ++ out_byte (0); /* DW_LNS_set_basic_block */ ++ out_byte (0); /* DW_LNS_const_add_pc */ ++ out_byte (1); /* DW_LNS_fixed_advance_pc */ ++ out_byte (0); /* DW_LNS_set_prologue_end */ ++ out_byte (0); /* DW_LNS_set_epilogue_begin */ ++ out_byte (1); /* DW_LNS_set_isa */ ++ ++ out_file_list (); ++ ++ symbol_set_value_now (prologue_end); ++ ++ /* For each section, emit a statement program. */ ++ output_something = 0; ++ for (s = all_segs; s; s = s->next) ++ output_something += process_entries (s->seg, s->head->head); ++ ++ /* ++ * If we have not output anything the tools on Mac OS X need to have a ++ * DW_LNE_set_address sequence to set the address to zero and a ++ * DW_LNE_end_sequence which consists of 3 bytes '00 01 01' ++ * (00 is the code for extended opcodes, followed by a ULEB128 length of the ++ * extended opcode (01), and the DW_LNE_end_sequence (01). ++ */ ++ if (output_something == 0) ++ { ++ /* ++ * This is the DW_LNE_set_address sequence to set the address to zero. ++ */ ++#ifdef ARCH64 ++ out_byte(0); ++ out_byte(9); ++ out_byte(2); ++ out_byte(0); ++ out_byte(0); ++ out_byte(0); ++ out_byte(0); ++ out_byte(0); ++ out_byte(0); ++ out_byte(0); ++ out_byte(0); ++#else ++ out_byte(0); ++ out_byte(5); ++ out_byte(2); ++ out_byte(0); ++ out_byte(0); ++ out_byte(0); ++ out_byte(0); ++#endif ++ out_byte(DW_LNS_extended_op); ++ out_byte(1); ++ out_byte(DW_LNE_end_sequence); ++ } ++ symbol_set_value_now (line_end); ++} ++ ++static void ++out_debug_ranges( ++struct frchain *ranges_section) ++{ ++ unsigned int addr_size = sizeof_address; ++ struct line_seg *s; ++ expressionS expr; ++ unsigned int i; ++ ++ section_set(ranges_section); ++ ++ /* Base Address Entry. */ ++ for (i = 0; i < addr_size; i++) ++ out_byte (0xff); ++ for (i = 0; i < addr_size; i++) ++ out_byte (0); ++ ++ /* Range List Entry. */ ++ for (s = all_segs; s; s = s->next) ++ { ++ fragS *frag; ++ symbolS *beg, *end; ++ ++ frag = first_frag_for_seg (s->seg); ++ beg = symbol_temp_new (s->seg, 0, frag); ++ s->text_start = beg; ++ ++ frag = last_frag_for_seg (s->seg); ++ end = symbol_temp_new (s->seg, get_frag_fix (frag, s->seg), frag); ++ s->text_end = end; ++ ++ memset(&expr, '\0', sizeof(expr)); ++ expr.X_op = O_symbol; ++ expr.X_add_symbol = beg; ++ expr.X_add_number = 0; ++ emit_expr (&expr, addr_size); ++ ++ memset(&expr, '\0', sizeof(expr)); ++ expr.X_op = O_symbol; ++ expr.X_add_symbol = end; ++ expr.X_add_number = 0; ++ emit_expr (&expr, addr_size); ++ } ++ ++ /* End of Range Entry. */ ++ for (i = 0; i < addr_size; i++) ++ out_byte (0); ++ for (i = 0; i < addr_size; i++) ++ out_byte (0); ++} ++ ++/* When generating debug info directly for assembly files, this routine is ++ called to emit data for .debug_aranges and or set the text_end field which ++ is used by out_debug_info() in the compile_unit. */ ++ ++static ++void ++out_debug_aranges( ++struct frchain *aranges_section, ++struct frchain *info_section) ++{ ++ unsigned int addr_size = sizeof_address; ++ addressT size, skip; ++ struct line_seg *s; ++ expressionS expr; ++ char *p; ++ ++ size = 4 + 2 + 4 + 1 + 1; ++ ++ skip = 2 * addr_size - (size & (2 * addr_size - 1)); ++ if (skip == 2 * addr_size) ++ skip = 0; ++ size += skip; ++ ++ for (s = all_segs; s; s = s->next) ++ size += 2 * addr_size; ++ ++ size += 2 * addr_size; ++ ++ section_set(aranges_section); ++ ++ /* Length of the compilation unit. */ ++ out_four (size - 4); ++ ++ /* Version. */ ++ out_two (2); ++ ++ /* Offset to .debug_info. */ ++ /* ??? sizeof_offset */ ++ TC_DWARF2_EMIT_OFFSET (section_symbol (info_section), 4); ++ ++ /* Size of an address (offset portion). */ ++ out_byte (addr_size); ++ ++ /* Size of a segment descriptor. */ ++ out_byte (0); ++ ++ /* Align the header. */ ++ if (skip) ++ { ++ char fill; ++ ++ fill = '\0'; ++ frag_align (ffs (2 * addr_size) - 1, &fill, 1, 0); ++ } ++ ++ for (s = all_segs; s; s = s->next) ++ { ++ fragS *frag; ++ symbolS *beg, *end; ++ ++ frag = first_frag_for_seg (s->seg); ++ beg = symbol_temp_new (s->seg, 0, frag); ++ s->text_start = beg; ++ ++ frag = last_frag_for_seg (s->seg); ++ end = symbol_temp_new (s->seg, get_frag_fix (frag, s->seg), frag); ++ s->text_end = end; ++ ++ memset(&expr, '\0', sizeof(expr)); ++ expr.X_op = O_symbol; ++ expr.X_add_symbol = beg; ++ expr.X_add_number = 0; ++ emit_expr (&expr, addr_size); ++ ++ memset(&expr, '\0', sizeof(expr)); ++#ifdef OLD ++ expr.X_op = O_subtract; ++#else ++ expr.X_seg = SEG_DIFFSECT; ++#endif ++ expr.X_add_symbol = end; ++#ifdef OLD ++ expr.X_op_symbol = beg; ++#else ++ expr.X_subtract_symbol = beg; ++#endif ++ expr.X_add_number = 0; ++ emit_expr (&expr, addr_size); ++ } ++ p = frag_more (2 * addr_size); ++ md_number_to_chars (p, 0, addr_size); ++ md_number_to_chars (p + addr_size, 0, addr_size); ++} ++ ++/* When generating debug info directly for assembly files, this routine is ++ called to output the data for .debug_abbrev. Note that this must be kept in ++ sync with out_debug_info below. */ ++ ++static ++void ++out_debug_abbrev( ++struct frchain * abbrev_section) ++{ ++ section_set(abbrev_section); ++ ++ /* DW_TAG_compile_unit DIE abbrev (1) */ ++ out_uleb128 (1); ++ out_uleb128 (DW_TAG_compile_unit); ++ out_byte (DW_CHILDREN_yes); ++ out_abbrev (DW_AT_stmt_list, DW_FORM_data4); ++ if (all_segs->next == NULL) ++ { ++ out_abbrev (DW_AT_low_pc, DW_FORM_addr); ++ out_abbrev (DW_AT_high_pc, DW_FORM_addr); ++ } ++ else ++ { ++ if (DWARF2_FORMAT () == dwarf2_format_32bit) ++ out_abbrev (DW_AT_ranges, DW_FORM_data4); ++ else ++ out_abbrev (DW_AT_ranges, DW_FORM_data8); ++ } ++ out_abbrev (DW_AT_name, DW_FORM_string); ++ out_abbrev (DW_AT_comp_dir, DW_FORM_string); ++ if(apple_flags != NULL) ++ out_abbrev (DW_AT_APPLE_flags, DW_FORM_string); ++ out_abbrev (DW_AT_producer, DW_FORM_string); ++ out_abbrev (DW_AT_language, DW_FORM_data2); ++ out_abbrev (0, 0); ++ ++ /* DW_TAG_subprogram DIE abbrev (2) */ ++ out_uleb128 (2); ++ out_uleb128 (DW_TAG_subprogram); ++ out_byte (DW_CHILDREN_yes); ++ out_abbrev (DW_AT_name, DW_FORM_string); ++ out_abbrev (DW_AT_decl_file, DW_FORM_data4); ++ out_abbrev (DW_AT_decl_line, DW_FORM_data4); ++ out_abbrev (DW_AT_low_pc, DW_FORM_addr); ++ out_abbrev (DW_AT_high_pc, DW_FORM_addr); ++ out_abbrev (DW_AT_prototyped, DW_FORM_flag); ++ out_abbrev (0, 0); ++ ++ /* DW_TAG_unspecified_parameters DIE abbrev (3) */ ++ out_uleb128 (3); ++ out_uleb128 (DW_TAG_unspecified_parameters); ++ out_byte (DW_CHILDREN_no); ++ out_abbrev (0, 0); ++ ++ /* Terminate the abbreviations for this compilation unit. */ ++ out_byte (0); ++} ++ ++/* When generating debug info directly for assembly files, this routine is ++ called to output the compilation unit and subprograms for .debug_info . */ ++ ++static ++void ++out_debug_info( ++struct frchain *info_section, ++struct frchain *abbrev_section, ++struct frchain *line_section, ++struct frchain *ranges_section) ++{ ++ char producer[128]; ++ char *comp_dir; ++ expressionS expr; ++ symbolS *info_start; ++ symbolS *info_end; ++ char *p; ++ int len; ++ enum dwarf2_format d2f; ++ int sizeof_offset; ++ struct dwarf2_subprogram_info *subs; ++ symbolS *prev_subs_symbol; ++ ++ sizeof_offset = 0; ++ section_set(info_section); ++ ++ info_start = symbol_temp_new_now (); ++ info_end = symbol_temp_make (); ++ ++ /* Compilation Unit length. */ ++ memset(&expr, '\0', sizeof(expr)); ++#ifdef OLD ++ expr.X_op = O_subtract; ++#else ++ expr.X_seg = SEG_DIFFSECT; ++#endif ++ expr.X_add_symbol = info_end; ++#ifdef OLD ++ expr.X_op_symbol = info_start; ++#else ++ expr.X_subtract_symbol = info_start; ++#endif ++ ++ d2f = DWARF2_FORMAT (); ++ if (d2f == dwarf2_format_32bit) ++ { ++ expr.X_add_number = -4; ++ emit_expr (&expr, 4); ++ sizeof_offset = 4; ++ } ++ else if (d2f == dwarf2_format_64bit) ++ { ++ expr.X_add_number = -12; ++ out_four (-1); ++ emit_expr (&expr, 8); ++ sizeof_offset = 8; ++ } ++ else if (d2f == dwarf2_format_64bit_irix) ++ { ++ expr.X_add_number = -8; ++ emit_expr (&expr, 8); ++ sizeof_offset = 8; ++ } ++ else ++ { ++ as_fatal (_("internal error: unknown dwarf2 format")); ++ } ++ ++ /* DWARF version. */ ++ out_two (2); ++ ++ /* .debug_abbrev offset */ ++ TC_DWARF2_EMIT_OFFSET (section_symbol (abbrev_section), sizeof_offset); ++ ++ /* Target address size. */ ++ out_byte (sizeof_address); ++ ++ /* DW_TAG_compile_unit DIE abbrev */ ++ out_uleb128 (1); ++ ++ /* DW_AT_stmt_list */ ++ /* ??? sizeof_offset */ ++ TC_DWARF2_EMIT_OFFSET (section_symbol (line_section), 4); ++ ++ /* These two attributes are emitted if all of the code is contiguous. */ ++ if (all_segs->next == NULL) ++ { ++ /* DW_AT_low_pc */ ++ memset(&expr, '\0', sizeof(expr)); ++ expr.X_op = O_symbol; ++ expr.X_add_symbol = all_segs->text_start; ++ expr.X_add_number = 0; ++ emit_expr (&expr, sizeof_address); ++ ++ /* DW_AT_high_pc */ ++ memset(&expr, '\0', sizeof(expr)); ++ expr.X_op = O_symbol; ++ expr.X_add_symbol = all_segs->text_end; ++ expr.X_add_number = 0; ++ emit_expr (&expr, sizeof_address); ++ } ++ else ++ { ++ /* This attribute is emitted if the code is disjoint. */ ++ /* DW_AT_ranges. */ ++ TC_DWARF2_EMIT_OFFSET (section_symbol (ranges_section), sizeof_offset); ++ } ++ ++ /* DW_AT_name. We don't have the actual file name that was present ++ on the command line, so assume files[1] is the main input file. ++ We're not supposed to get called unless at least one line number ++ entry was emitted, so this should always be defined. */ ++ if (!files || files_in_use < 1) ++ abort (); ++ if (files[1].dir) ++ { ++ len = strlen (dirs[files[1].dir]); ++ p = frag_more (len + 1); ++ memcpy (p, dirs[files[1].dir], len); ++ INSERT_DIR_SEPARATOR (p, len); ++ } ++ len = strlen (files[1].filename) + 1; ++ p = frag_more (len); ++ memcpy (p, files[1].filename, len); ++ ++ /* DW_AT_comp_dir */ ++#ifdef OLD ++ comp_dir = getpwd (); ++#else ++ comp_dir = getwd(xmalloc(MAXPATHLEN + 1)); ++#endif ++ len = strlen (comp_dir) + 1; ++ p = frag_more (len); ++ memcpy (p, comp_dir, len); ++ ++ if(apple_flags != NULL){ ++ /* DW_AT_APPLE_flags */ ++ len = strlen (apple_flags) + 1; ++ p = frag_more (len); ++ memcpy (p, apple_flags, len); ++ } ++ ++ /* DW_AT_producer */ ++ sprintf (producer, "%s %s, %s", APPLE_INC_VERSION, apple_version, ++ version_string); ++ len = strlen (producer) + 1; ++ p = frag_more (len); ++ memcpy (p, producer, len); ++ ++ /* DW_AT_language. Yes, this is probably not really MIPS, but the ++ dwarf2 draft has no standard code for assembler. */ ++ out_two (DW_LANG_Mips_Assembler); ++ ++ prev_subs_symbol = NULL; ++ for(subs = dwarf2_subprograms_info; subs != NULL; subs = subs->next){ ++ uint32_t n_sect; ++ fragS *frag; ++ symbolS *end; ++ struct dwarf2_subprogram_info *subs_next; ++ ++ /* Don't emit zero length TAG_subprogram dwarf debug info. */ ++ if(prev_subs_symbol != NULL && ++ prev_subs_symbol->sy_frag == subs->symbol->sy_frag && ++ prev_subs_symbol->sy_value == subs->symbol->sy_value) ++ { ++ continue; ++ } ++ else ++ { ++ prev_subs_symbol = subs->symbol; ++ } ++ ++ /* DW_TAG_subprogram DIE abbrev */ ++ out_uleb128 (2); ++ ++ /* DW_AT_name */ ++ len = strlen (subs->name) + 1; ++ p = frag_more (len); ++ memcpy (p, subs->name, len); ++ ++ /* DW_AT_decl_file */ ++ out_four (subs->file_number); ++ ++ /* DW_AT_decl_line */ ++ out_four (subs->line_number); ++ ++ /* DW_AT_low_pc */ ++ memset(&expr, '\0', sizeof(expr)); ++ expr.X_op = O_symbol; ++ expr.X_add_symbol = subs->symbol; ++ expr.X_add_number = 0; ++ emit_expr (&expr, sizeof_address); ++ ++ /* DW_AT_high_pc */ ++ end = NULL; ++ if(subs->next != NULL) ++ { ++ end = subs->next->symbol; ++ subs_next = subs->next; ++ while(subs->symbol->sy_frag == end->sy_frag && ++ subs->symbol->sy_value == end->sy_value) ++ { ++ if(subs_next->next == NULL) ++ { ++ end = NULL; ++ break; ++ } ++ else ++ { ++ subs_next = subs_next->next; ++ end = subs_next->symbol; ++ } ++ } ++ } ++ if(end == NULL) ++ { ++ n_sect = subs->symbol->sy_nlist.n_sect; ++ frag = last_frag_for_seg (n_sect); ++ end = symbol_temp_new (n_sect, get_frag_fix (frag, n_sect), frag); ++ } ++ memset(&expr, '\0', sizeof(expr)); ++ expr.X_op = O_symbol; ++ expr.X_add_symbol = end; ++ expr.X_add_number = 0; ++ emit_expr (&expr, sizeof_address); ++ ++ /* DW_AT_prototyped */ ++ out_byte (0); ++ ++ /* DW_TAG_unspecified_parameters DIE abbrev */ ++ out_uleb128 (3); ++ /* Add the NULL DIE terminating the DW_TAG_unspecified_parameters DIE's. */ ++ out_byte (0); ++ } ++ ++ /* Add the NULL DIE terminating the Compile Unit DIE's. */ ++ out_byte (0); ++ ++ symbol_set_value_now (info_end); ++} ++ ++/* Finish the dwarf2 debug sections. We emit .debug.line if there ++ were any .file/.loc directives, or --gdwarf2 was given, or if the ++ file has a non-empty .debug_info section. If we emit .debug_line, ++ and the .debug_info section is empty, we also emit .debug_info, ++ .debug_aranges and .debug_abbrev. ALL_SEGS will be non-null if ++ there were any .file/.loc directives, or --gdwarf2 was given and ++ there were any located instructions emitted. */ ++ ++void ++dwarf2_finish (void) ++{ ++#ifdef OLD ++ segT info_seg; ++ segT line_seg; ++#else ++ struct frchain *info_section, *line_section; ++#endif ++ struct line_seg *s; ++ int emit_other_sections = 0; ++ ++#ifdef OLD ++ info_seg = bfd_get_section_by_name (stdoutput, ".debug_info"); ++ emit_other_sections = info_seg == NULL || !seg_not_empty_p (info_seg); ++#else ++ info_section = get_section_by_name("__DWARF", "__debug_info"); ++ emit_other_sections = info_section == NULL || !seg_not_empty_p(info_section); ++#endif ++ ++ if (!all_segs && emit_other_sections && files_in_use == 0) ++ /* There is no line information and no non-empty .debug_info ++ section. */ ++ return; ++ ++ /* To make get_frag_fix() work we force what would happen in ++ layout_addresses to add a last zero sized frag to each section. */ ++ add_last_frags_to_sections(); ++ ++ /* Calculate the size of an address for the target machine. */ ++#ifdef OLD ++ sizeof_address = DWARF2_ADDR_SIZE (stdoutput); ++#else ++ if(md_cputype & CPU_ARCH_ABI64) ++ sizeof_address = 8; ++ else ++ sizeof_address = 4; ++#endif ++ ++ /* Create and switch to the line number section. */ ++#ifdef OLD ++ line_seg = subseg_new (".debug_line", 0); ++ bfd_set_section_flags (stdoutput, line_seg, SEC_READONLY | SEC_DEBUGGING); ++#else ++ line_section = section_new("__DWARF", "__debug_line", ++ S_REGULAR, S_ATTR_DEBUG, 0); ++#endif ++ ++ /* For each subsection, chain the debug entries together. */ ++ for (s = all_segs; s; s = s->next) ++ { ++ struct line_subseg *ss = s->head; ++ struct line_entry **ptail = ss->ptail; ++ ++ while ((ss = ss->next) != NULL) ++ { ++ *ptail = ss->head; ++ ptail = ss->ptail; ++ } ++ } ++ ++#ifdef OLD ++ out_debug_line (line_seg); ++#else ++ /* If might be possible that an older compiler is not using .file and .loc ++ in that case make sure not to put out a second empty line table. But it ++ is possible only .file is used and in that case put out the line table. */ ++ if(all_segs != NULL || files_in_use) ++ out_debug_line (line_section); ++#endif ++ ++ /* If this is assembler generated line info, and there is no ++ debug_info already, we need .debug_info and .debug_abbrev ++ sections as well. */ ++ if (emit_other_sections) ++ { ++#ifdef OLD ++ segT abbrev_seg; ++ segT aranges_seg; ++ segT ranges_seg; ++#else ++ struct frchain *abbrev_section, *aranges_section, *ranges_section; ++#endif ++ ++ assert (all_segs); ++ ++#ifdef OLD ++ info_seg = subseg_new (".debug_info", 0); ++ abbrev_seg = subseg_new (".debug_abbrev", 0); ++ aranges_seg = subseg_new (".debug_aranges", 0); ++ ++ bfd_set_section_flags (stdoutput, info_seg, ++ SEC_READONLY | SEC_DEBUGGING); ++ bfd_set_section_flags (stdoutput, abbrev_seg, ++ SEC_READONLY | SEC_DEBUGGING); ++ bfd_set_section_flags (stdoutput, aranges_seg, ++ SEC_READONLY | SEC_DEBUGGING); ++ ++ record_alignment (aranges_seg, ffs (2 * sizeof_address) - 1); ++#else ++ info_section = section_new("__DWARF", "__debug_info", ++ S_REGULAR, S_ATTR_DEBUG, 0); ++ abbrev_section = section_new("__DWARF", "__debug_abbrev", ++ S_REGULAR, S_ATTR_DEBUG, 0); ++ aranges_section = section_new("__DWARF", "__debug_aranges", ++ S_REGULAR, S_ATTR_DEBUG, 0); ++ /* ++ * The alignment of the Mach-O (__DWARF, __debug_aranges) is the default ++ * 1-byte alignment, 2^0, so the aranges_section->frch_section->align ++ * field should remain zero and not changed. ++ */ ++#endif ++ ++ if (all_segs == NULL || all_segs->next == NULL) ++#ifdef OLD ++ ranges_seg = NULL; ++#else ++ ranges_section = NULL; ++#endif ++ else ++ { ++#ifdef OLD ++ ranges_seg = subseg_new (".debug_ranges", 0); ++ bfd_set_section_flags (stdoutput, ranges_seg, ++ SEC_READONLY | SEC_DEBUGGING); ++ record_alignment (ranges_seg, ffs (2 * sizeof_address) - 1); ++ out_debug_ranges (ranges_seg); ++#else ++ ranges_section = section_new("__DWARF", "__debug_ranges", ++ S_REGULAR, S_ATTR_DEBUG, 0); ++ /* ++ * The alignment of the Mach-O (__DWARF, __debug_ranges) is the ++ * default 1-byte alignment, 2^0, so the ++ * ranges_section->frch_section->align field should remain zero ++ * and not changed. ++ */ ++ out_debug_ranges (ranges_section); ++#endif ++ } ++ ++#ifdef OLD ++ out_debug_aranges (aranges_seg, info_seg); ++ out_debug_abbrev (abbrev_seg); ++ out_debug_info (info_seg, abbrev_seg, line_seg, ranges_seg); ++#else ++ if (all_segs != NULL && ++ (all_segs->next != NULL || debug_type == DEBUG_DWARF2)) ++ { ++ out_debug_aranges (aranges_section, info_section); ++ out_debug_abbrev (abbrev_section); ++ out_debug_info (info_section, abbrev_section, line_section, ++ ranges_section); ++ } ++#endif ++ } ++} ++ ++/* ++ * macho_dwarf2_emit_offset() is used via the TC_DWARF2_EMIT_OFFSET macro to ++ * output an "offset". Where it is used the offset is to the start of ++ * information in a specific section for a field in another section. This ++ * appears to always be passed the section_symbol() for the specific section ++ * and that offset is always to the start of that section. So this is why ++ * we put out zeros. ++ */ ++static void ++macho_dwarf2_emit_offset( ++symbolS *symbol, ++unsigned int size) ++{ ++ unsigned int i; ++ ++ for(i = 0; i < size; i++) ++ out_byte(0); ++} +Index: odcctools-9.2-ld/as/dwarf2dbg.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ odcctools-9.2-ld/as/dwarf2dbg.h 2013-09-03 21:08:01.885209515 +0000 +@@ -0,0 +1,139 @@ ++/* dwarf2dbg.h - DWARF2 debug support ++ Copyright 1999, 2000, 2002, 2003 Free Software Foundation, Inc. ++ ++ This file is part of GAS, the GNU Assembler. ++ ++ GAS is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2, or (at your option) ++ any later version. ++ ++ GAS is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with GAS; see the file COPYING. If not, write to the Free ++ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA ++ 02110-1301, USA. */ ++ ++#ifndef AS_DWARF2DBG_H ++#define AS_DWARF2DBG_H ++ ++/* HACKS for bfd_* and BFD_RELOC_* These would come from bfd/reloc.c */ ++typedef int bfd_boolean; ++ ++#include "as.h" ++ ++#define DWARF2_FLAG_IS_STMT (1 << 0) ++#define DWARF2_FLAG_BASIC_BLOCK (1 << 1) ++#define DWARF2_FLAG_PROLOGUE_END (1 << 2) ++#define DWARF2_FLAG_EPILOGUE_BEGIN (1 << 3) ++ ++struct dwarf2_line_info { ++ unsigned int filenum; ++ unsigned int line; ++ unsigned int column; ++ unsigned int isa; ++ unsigned int flags; ++}; ++ ++/* When creating dwarf2 debugging information for assembly files, the variable ++ dwarf2_file_number is used to generate a .file for each assembly source file ++ in read_a_source_file() in read.c . */ ++extern uint32_t dwarf2_file_number; ++ ++/* Info that is needed to be gathered for each symbol that will have a ++ dwarf2_subprogram when generating debug info directly for assembly files. ++ This is done in make_subprogram_for_symbol() in symbols.c . */ ++struct dwarf2_subprogram_info { ++ char *name; /* without a leading underbar, if any */ ++ uint32_t file_number; /* the dwarf file number this symbol is in */ ++ uint32_t line_number; /* the line number this symbol is at */ ++ /* ++ * The low_pc for the dwarf2_subprogram is taken from the symbol's ++ * n_value. The high_pc is taken from the next symbol's value or ++ * the end of the section for the last symbol. ++ */ ++ symbolS *symbol; ++ struct dwarf2_subprogram_info *next; ++}; ++extern struct dwarf2_subprogram_info *dwarf2_subprograms_info; ++ ++/* Implements the .file FILENO "FILENAME" directive. FILENO can be 0 ++ to indicate that no file number has been assigned. All real file ++ number must be >0. */ ++extern char *dwarf2_directive_file (uintptr_t dummy); ++ ++/* ++ * dwarf2_file() is what is called when generating ++ * debug info directly for assembly files with --gdwarf2. ++ */ ++extern void dwarf2_file (char *filename, offsetT num); ++ ++/* Implements the .loc FILENO LINENO [COLUMN] directive. FILENO is ++ the file number, LINENO the line number and the (optional) COLUMN ++ the column of the source code that the following instruction ++ corresponds to. FILENO can be 0 to indicate that the filename ++ specified by the textually most recent .file directive should be ++ used. */ ++extern void dwarf2_directive_loc (uintptr_t dummy); ++ ++/* ++ * dwarf2_loc() is what is called when generating ++ * debug info directly for assembly files with --gdwarf2. ++ */ ++extern void dwarf2_loc (offsetT filenum, offsetT line); ++ ++/* Implements the .loc_mark_labels {0,1} directive. */ ++extern void dwarf2_directive_loc_mark_labels (uintptr_t dummy); ++ ++/* Returns the current source information. If .file directives have ++ been encountered, the info for the corresponding source file is ++ returned. Otherwise, the info for the assembly source file is ++ returned. */ ++extern void dwarf2_where (struct dwarf2_line_info *l); ++ ++/* A hook to allow the target backend to inform the line number state ++ machine of isa changes when assembler debug info is enabled. */ ++extern void dwarf2_set_isa (unsigned int isa); ++ ++/* This function generates .debug_line info based on the address and ++ source information passed in the arguments. ADDR should be the ++ frag-relative offset of the instruction the information is for and ++ L is the source information that should be associated with that ++ address. */ ++extern void dwarf2_gen_line_info (addressT addr, struct dwarf2_line_info *l); ++ ++/* Must be called for each generated instruction. */ ++extern void dwarf2_emit_insn (int); ++ ++/* Should be called for each code label. */ ++extern void dwarf2_emit_label (symbolS *); ++ ++/* True when we're supposed to set the basic block mark whenever a label ++ is seen. Unless the target is doing Something Weird, just call ++ dwarf2_emit_label. */ ++extern bfd_boolean dwarf2_loc_mark_labels; ++ ++extern void dwarf2_finish (void); ++ ++extern int dwarf2dbg_estimate_size_before_relax (fragS *); ++extern int dwarf2dbg_relax_frag (fragS *); ++extern void dwarf2dbg_convert_frag (fragS *); ++ ++/* An enumeration which describes the sizes of offsets (to DWARF sections) ++ and the mechanism by which the size is indicated. */ ++enum dwarf2_format { ++ /* 32-bit format: the initial length field is 4 bytes long. */ ++ dwarf2_format_32bit, ++ /* DWARF3 64-bit format: the representation of the initial length ++ (of a DWARF section) is 0xffffffff (4 bytes) followed by eight ++ bytes indicating the actual length. */ ++ dwarf2_format_64bit, ++ /* SGI extension to DWARF2: The initial length is eight bytes. */ ++ dwarf2_format_64bit_irix ++}; ++ ++#endif /* AS_DWARF2DBG_H */ +Index: odcctools-9.2-ld/as/expr.c +=================================================================== +--- odcctools-9.2-ld.orig/as/expr.c 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/as/expr.c 2013-09-03 21:08:01.889209515 +0000 +@@ -72,7 +72,9 @@ + + O_bit_inclusive_or, /* (16) | */ + O_bit_or_not, /* (17) ! */ +- two_char_operator /* (18) encoding for two char operator */ ++ O_logical_and, /* (18) && */ ++ O_logical_or, /* (19) || */ ++ two_char_operator /* (20) encoding for two char operator */ + } operatorT; + + static segT expr( +@@ -239,24 +241,26 @@ + * which is used to advance the input_line_pointer over the operator. + */ + static int op_size [] = +- { 0, 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1 }; ++ { 0, 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2 }; + + /* + * op_rank is indexed by an operatorT and tells the rank of the operator. + * + * Rank Examples +- * 8 * / % +- * 7 + - +- * 6 >> << +- * 5 < > <= >= +- * 4 == != +- * 3 & +- * 2 ^ +- * 1 | ! ++ * 10 * / % ++ * 9 + - ++ * 8 >> << ++ * 7 < > <= >= ++ * 6 == != ++ * 5 & ++ * 4 ^ ++ * 3 | ! ++ * 2 && ++ * 1 || + * 0 operand, (expression) + */ + static operator_rankT op_rank [] = +- { 0, 8, 8, 8, 7, 7, 6, 6, 5, 5, 5, 5, 4, 4, 3, 2, 1, 1 }; ++ { 0,10,10,10, 9, 9, 8, 8, 7, 7, 7, 7, 6, 6, 5, 4, 3, 3, 2, 1 }; + + /* + * op_encoding is indexed by a an ASCII character and maps it to an operator. +@@ -266,7 +270,7 @@ + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + +- __, two_char_operator, __, __, __, O_modulus, O_bit_and, __, ++ __, two_char_operator, __, __, __, O_modulus, two_char_operator, __, + __, __, O_multiply, O_add, __, O_subtract, __, O_divide, + __, __, __, __, __, __, __, __, + __, __, __, __, two_char_operator, two_char_operator, two_char_operator, __, +@@ -277,7 +281,7 @@ + __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, +- __, __, __, __, O_bit_inclusive_or, __, __, __, ++ __, __, __, __, two_char_operator, __, __, __, + + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, +@@ -448,7 +452,8 @@ + } + else{ + if(seg2 == SEG_ABSOLUTE){ +- resultP->X_seg = seg1; ++ if(resultP->X_seg != SEG_DIFFSECT) ++ resultP->X_seg = seg1; + } + else{ + /* also know seg2 != -1 (SEG_PASS1) */ +@@ -510,6 +515,19 @@ + */ + try_to_make_absolute(resultP); + try_to_make_absolute(&right); ++ /* ++ * If we have the special assembly time constant expression ++ * of the difference of two symbols defined in the same ++ * section then divided by exactly 2 mark the expression ++ * indicating this. ++ */ ++ if(resultP->X_seg == SEG_DIFFSECT && ++ right.X_seg == SEG_ABSOLUTE && ++ op_left == O_divide && ++ right.X_add_number == 2){ ++ resultP->X_sectdiff_divide_by_two = 1; ++ goto down; ++ } + resultP->X_subtract_symbol = NULL; + resultP->X_add_symbol = NULL; + if(resultP->X_seg != SEG_ABSOLUTE || +@@ -527,6 +545,11 @@ + case O_bit_inclusive_or: + resultP->X_add_number |= right.X_add_number; + break; ++ ++ case O_logical_or: ++ resultP->X_add_number = ++ resultP->X_add_number || right.X_add_number; ++ break; + + case O_modulus: + if(right.X_add_number){ +@@ -542,6 +565,11 @@ + case O_bit_and: + resultP->X_add_number &= right.X_add_number; + break; ++ ++ case O_logical_and: ++ resultP->X_add_number = ++ resultP->X_add_number && right.X_add_number; ++ break; + + case O_multiply: + resultP->X_add_number *= right.X_add_number; +@@ -618,6 +646,7 @@ + break; + } /* switch(op_left) */ + } ++down: ; + } /* If we have to force need_pass_2 */ + } /* If operator was + */ + op_left = op_right; +@@ -776,7 +805,7 @@ + LITTLENUM_TYPE *leader; + /* -> littlenum we are frobbing now. */ + LITTLENUM_TYPE *pointer; +- long carry; ++ int32_t carry; + + leader = generic_bignum; + generic_bignum [0] = 0; +@@ -789,7 +818,7 @@ + for(pointer = generic_bignum; + pointer <= leader; + pointer++){ +- long work; ++ int32_t work; + + work = carry + radix * *pointer; + *pointer = work & LITTLENUM_MASK; +@@ -827,68 +856,60 @@ + * mean the same as the (conventional) "9f". This is simply + * easier than checking for strict canonical form. + */ +- if(number < 10){ +- if(c == 'b'){ +- /* +- * Backward ref to local label. +- * Because it is backward, expect it to be DEFINED. +- */ +- /* +- * Construct a local label. +- */ +- name = local_label_name((int)number, 0); +- symbolP = symbol_table_lookup(name); +- if((symbolP != NULL) && +- (symbolP->sy_type & N_TYPE) != N_UNDF){ +- /* Expected path: symbol defined. */ +- /* Local labels are never absolute. Don't waste +- time checking absoluteness. */ +- know((symbolP->sy_type & N_TYPE) == N_SECT); +- expressionP->X_add_symbol = symbolP; +- expressionP->X_add_number = 0; +- expressionP->X_seg = SEG_SECT; +- } +- else{ /* Either not seen or not defined. */ +- as_warn("Backw. ref to unknown label \"%lld\"," +- "0 assumed.", number); +- expressionP->X_add_number = 0; +- expressionP->X_seg = SEG_ABSOLUTE; +- } +- } +- else if(c == 'f'){ +- /* +- * Forward reference. Expect symbol to be +- * undefined or unknown. Undefined: seen it +- * before. Unknown: never seen it in this pass. +- * Construct a local label name, then an +- * undefined symbol. Don't create a XSEG frag +- * for it: caller may do that. +- * Just return it as never seen before. +- */ +- name = local_label_name((int)number, 1); +- symbolP = symbol_table_lookup(name); +- if(symbolP != NULL){ +- /* We have no need to check symbol +- properties. */ +- know((symbolP->sy_type & N_TYPE) == N_UNDF || +- (symbolP->sy_type & N_TYPE) == N_SECT); +- } +- else{ +- symbolP = symbol_new(name, N_UNDF, 0,0,0, +- &zero_address_frag); +- symbol_table_insert(symbolP); +- } +- expressionP->X_add_symbol = symbolP; +- expressionP->X_seg = SEG_UNKNOWN; +- expressionP->X_subtract_symbol = NULL; +- expressionP->X_add_number = 0; ++ if(c == 'b'){ ++ /* ++ * Backward ref to local label. ++ * Because it is backward, expect it to be DEFINED. ++ */ ++ /* ++ * Construct a local label. ++ */ ++ name = fb_label_name((int)number, 0); ++ symbolP = symbol_table_lookup(name); ++ if((symbolP != NULL) && ++ (symbolP->sy_type & N_TYPE) != N_UNDF){ ++ /* Expected path: symbol defined. */ ++ /* Local labels are never absolute. Don't waste ++ time checking absoluteness. */ ++ know((symbolP->sy_type & N_TYPE) == N_SECT); ++ expressionP->X_add_symbol = symbolP; ++ expressionP->X_add_number = 0; ++ expressionP->X_seg = SEG_SECT; + } +- else{ /* Really a number, not a local label. */ +- ignore_c_ll_or_ull(c); +- expressionP->X_add_number = number; ++ else{ /* Either not seen or not defined. */ ++ as_warn("Backw. ref to unknown label \"%lld\"," ++ "0 assumed.", number); ++ expressionP->X_add_number = 0; + expressionP->X_seg = SEG_ABSOLUTE; +- input_line_pointer--; /* restore following char */ +- } ++ } ++ } ++ else if(c == 'f'){ ++ /* ++ * Forward reference. Expect symbol to be ++ * undefined or unknown. Undefined: seen it ++ * before. Unknown: never seen it in this pass. ++ * Construct a local label name, then an ++ * undefined symbol. Don't create a XSEG frag ++ * for it: caller may do that. ++ * Just return it as never seen before. ++ */ ++ name = fb_label_name((int)number, 1); ++ symbolP = symbol_table_lookup(name); ++ if(symbolP != NULL){ ++ /* We have no need to check symbol ++ properties. */ ++ know((symbolP->sy_type & N_TYPE) == N_UNDF || ++ (symbolP->sy_type & N_TYPE) == N_SECT); ++ } ++ else{ ++ symbolP = symbol_new(name, N_UNDF, 0,0,0, ++ &zero_address_frag); ++ symbol_table_insert(symbolP); ++ } ++ expressionP->X_add_symbol = symbolP; ++ expressionP->X_seg = SEG_UNKNOWN; ++ expressionP->X_subtract_symbol = NULL; ++ expressionP->X_add_number = 0; + } + else{ /* a number >= 10 */ + ignore_c_ll_or_ull(c); +@@ -988,7 +1009,7 @@ + * then assigning it to the 64-bit value the expression + * will be correct. + */ +- (long) ++ (int32_t) + #endif + symbolP->sy_value; + } +@@ -1333,7 +1354,7 @@ + * any machine dependent frags of variable length in the + * chain. + */ +- unsigned long size, fail; ++ uint32_t size, fail; + struct frag *frag; + + if(add_symbol->sy_frag != NULL && +@@ -1407,6 +1428,14 @@ + if(second_op_char == '=') + return(O_not_equal); + return O_not_equal; ++ case '&': ++ if(second_op_char == '&') ++ return(O_logical_and); ++ return(O_bit_and); ++ case '|': ++ if(second_op_char == '|') ++ return(O_logical_or); ++ return(O_bit_inclusive_or); + default: + BAD_CASE(first_op_char); + return O_illegal; +Index: odcctools-9.2-ld/as/expr.h +=================================================================== +--- odcctools-9.2-ld.orig/as/expr.h 2013-09-03 21:08:01.405209526 +0000 ++++ odcctools-9.2-ld/as/expr.h 2013-09-03 21:08:01.889209515 +0000 +@@ -102,7 +102,12 @@ + O_constant must be extended into a bignum (i.e., it is not used + when performing arithmetic on these values). + FIXME: This field is not set very reliably. */ +- unsigned int X_unsigned : 1; ++ unsigned int X_unsigned : 1, ++ ++ /* Non-zero if we have the special assembly time constant expression ++ of the difference of two symbols defined in the same section then divided ++ by exactly 2. */ ++ X_sectdiff_divide_by_two : 1; + } expressionS; + + extern segT expression( +Index: odcctools-9.2-ld/as/md.h +=================================================================== +--- odcctools-9.2-ld.orig/as/md.h 2013-09-03 21:08:01.405209526 +0000 ++++ odcctools-9.2-ld/as/md.h 2013-09-03 21:08:01.889209515 +0000 +@@ -161,5 +161,5 @@ + * md_pcrel_from() returns the PC-relative offset from the given fixup. + * This is not implemented or used for most targets. + */ +-extern long md_pcrel_from( ++extern int32_t md_pcrel_from( + const fixS *fixP); +Index: odcctools-9.2-ld/as/struc-symbol.h +=================================================================== +--- odcctools-9.2-ld.orig/as/struc-symbol.h 2013-09-03 21:08:01.405209526 +0000 ++++ odcctools-9.2-ld/as/struc-symbol.h 2013-09-03 21:08:01.889209515 +0000 +@@ -33,17 +33,17 @@ + struct symbol /* our version of an nlist node */ + { + nlist_t sy_nlist; /* what we write in .o file (if permitted) */ +-#ifdef ARCH64 + char *sy_name; /* symbol name */ +-#endif +- long unsigned sy_name_offset; /* 1-origin position of sy_name in symbols */ ++ uint32_t sy_name_offset; /* 1-origin position of sy_name in symbols */ + /* part of object file. */ + /* 0 for (nameless) .stabd symbols. */ + /* Not used until write_object() time. */ +- long int sy_number; /* 24 bit symbol number. */ ++ uint32_t sy_number; /* 24 bit symbol number. */ + /* Symbol numbers start at 0 and are */ + /* unsigned. */ + struct symbol *sy_prev_by_index; /* backward chain, or NULL */ ++ int sy_has_been_resolved; /* if true the next fieid is set */ ++ struct symbol *sy_prev_resolved; /* first non local in backward chain */ + struct symbol *sy_next; /* forward chain, or NULL */ + struct frag *sy_frag; /* NULL or -> frag this symbol attaches to. */ + struct symbol *sy_forward; /* value is really that of this other symbol */ +@@ -57,11 +57,8 @@ + + typedef struct symbol symbolS; + +-#ifndef ARCH64 +-#define sy_name sy_nlist .n_un. n_name +- /* Name field always points to a string. */ +- /* 0 means .stabd-like anonymous symbol. */ +-#endif ++/* sy_name - Name field always points to a string. */ ++/* 0 means .stabd-like anonymous symbol. */ + #define sy_type sy_nlist. n_type + #ifdef NeXT_MOD + #define sy_other sy_nlist. n_sect +@@ -77,7 +74,7 @@ + struct indirect_symbol { + char *isy_name; /* name of the indirect */ + struct frag *isy_frag; /* frag this indirect attaches to */ +- unsigned long isy_offset; /* offset into frag this attaches to */ ++ uint32_t isy_offset; /* offset into frag this attaches to */ + struct symbol *isy_symbol; /* symbol for the indirect */ + struct indirect_symbol *isy_next; /* forward chain, or NULL */ + }; +Index: odcctools-9.2-ld/as/symbols.c +=================================================================== +--- odcctools-9.2-ld.orig/as/symbols.c 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/as/symbols.c 2013-09-03 21:08:01.889209515 +0000 +@@ -19,6 +19,7 @@ + + #include <stdlib.h> + #include <string.h> ++#include <ctype.h> + #include "as.h" + #include "hash.h" + #include "obstack.h" /* For "symbols.h" */ +@@ -32,6 +33,7 @@ + #include "messages.h" + #include "fixes.h" + #include "input-scrub.h" ++#include "dwarf2dbg.h" + + /* symbol-name => struct symbol pointer */ + struct hash_control *sy_hash = NULL; +@@ -69,16 +71,14 @@ + + typedef short unsigned int local_label_countT; + +-static local_label_countT local_label_counter[10]; +- +-static /* Returned to caller, then copied. */ +- char symbol_name_build[12]; /* used for created names ("4f") */ +- +-static long int symbol_count = 0; /* The number of symbols we've declared. */ +- + static void make_stab_for_symbol( + symbolS *symbolP); + ++static void make_subprogram_for_symbol( ++ symbolS *symbolP); ++ ++static void fb_label_init(void); ++ + + void + symbol_begin( +@@ -89,56 +89,225 @@ + sy_hash = hash_new(); + memset((char *)(&abs_symbol), '\0', sizeof(abs_symbol)); + abs_symbol.sy_type = N_ABS; /* Can't initialise a union. Sigh. */ +- memset((char *)(local_label_counter), '\0', sizeof(local_label_counter) ); ++ fb_label_init (); + } + +-/* +- * local_label_name() +- * +- * Caller must copy returned name: we re-use the area for the next name. +- */ +-char * /* Return local label name. */ +-local_label_name( +-int n, /* we just saw "n:", "nf" or "nb" : n a digit */ +-int augend) /* 0 for nb, 1 for n:, nf */ ++ ++/* Somebody else's idea of local labels. They are made by "n:" where n ++ is any decimal digit. Refer to them with ++ "nb" for previous (backward) n: ++ or "nf" for next (forward) n:. ++ ++ We do a little better and let n be any number, not just a single digit, but ++ since the other guy's assembler only does ten, we treat the first ten ++ specially. ++ ++ Like someone else's assembler, we have one set of local label counters for ++ entire assembly, not one set per (sub)segment like in most assemblers. This ++ implies that one can refer to a label in another segment, and indeed some ++ crufty compilers have done just that. ++ ++ Since there could be a LOT of these things, treat them as a sparse ++ array. */ ++ ++#define LOCAL_LABEL_CHAR '\002' ++#define FB_LABEL_SPECIAL (10) ++ ++static int32_t fb_low_counter[FB_LABEL_SPECIAL]; ++static int32_t *fb_labels; ++static int32_t *fb_label_instances; ++static int32_t fb_label_count; ++static int32_t fb_label_max; ++ ++/* This must be more than FB_LABEL_SPECIAL. */ ++#define FB_LABEL_BUMP_BY (FB_LABEL_SPECIAL + 6) ++ ++static void ++fb_label_init (void) ++{ ++ memset ((void *) fb_low_counter, '\0', sizeof (fb_low_counter)); ++} ++ ++/* Add one to the instance number of this fb label. */ ++ ++void ++fb_label_instance_inc (int32_t label) + { +- register char * p; +- register char * q; +- char symbol_name_temporary[10]; /* build up a number, BACKWARDS */ ++ int32_t *i; ++ ++ if (label < FB_LABEL_SPECIAL) ++ { ++ ++fb_low_counter[label]; ++ return; ++ } ++ ++ if (fb_labels != NULL) ++ { ++ for (i = fb_labels + FB_LABEL_SPECIAL; ++ i < fb_labels + fb_label_count; ++i) ++ { ++ if (*i == label) ++ { ++ ++fb_label_instances[i - fb_labels]; ++ return; ++ } /* if we find it */ ++ } /* for each existing label */ ++ } + +- know( n >= 0 ); +- know( augend == 0 || augend == 1 ); ++ /* If we get to here, we don't have label listed yet. */ ++ ++ if (fb_labels == NULL) ++ { ++ fb_labels = (int32_t *) xmalloc (FB_LABEL_BUMP_BY * sizeof (int32_t)); ++ fb_label_instances = (int32_t *) xmalloc (FB_LABEL_BUMP_BY * sizeof (int32_t)); ++ fb_label_max = FB_LABEL_BUMP_BY; ++ fb_label_count = FB_LABEL_SPECIAL; ++ ++ } ++ else if (fb_label_count == fb_label_max) ++ { ++ fb_label_max += FB_LABEL_BUMP_BY; ++ fb_labels = (int32_t *) xrealloc ((char *) fb_labels, ++ fb_label_max * sizeof (int32_t)); ++ fb_label_instances = (int32_t *) xrealloc ((char *) fb_label_instances, ++ fb_label_max * sizeof (int32_t)); ++ } /* if we needed to grow */ ++ ++ fb_labels[fb_label_count] = label; ++ fb_label_instances[fb_label_count] = 1; ++ ++fb_label_count; ++} ++ ++static int32_t ++fb_label_instance (int32_t label) ++{ ++ int32_t *i; ++ ++ if (label < FB_LABEL_SPECIAL) ++ { ++ return (fb_low_counter[label]); ++ } ++ ++ if (fb_labels != NULL) ++ { ++ for (i = fb_labels + FB_LABEL_SPECIAL; ++ i < fb_labels + fb_label_count; ++i) ++ { ++ if (*i == label) ++ { ++ return (fb_label_instances[i - fb_labels]); ++ } /* if we find it */ ++ } /* for each existing label */ ++ } ++ ++ /* We didn't find the label, so this must be a reference to the ++ first instance. */ ++ return 0; ++} ++ ++/* Caller must copy returned name: we re-use the area for the next name. ++ ++ The mth occurence of label n: is turned into the symbol "Ln^Bm" ++ where n is the label number and m is the instance number. "L" makes ++ it a label discarded unless debugging and "^B"('\2') ensures no ++ ordinary symbol SHOULD get the same name as a local label ++ symbol. The first "4:" is "L4^B1" - the m numbers begin at 1. */ ++ ++char * /* Return local label name. */ ++fb_label_name (int32_t n, /* We just saw "n:", "nf" or "nb" : n a number. */ ++ int32_t augend /* 0 for nb, 1 for n:, nf. */) ++{ ++ int32_t i; ++ /* Returned to caller, then copied. Used for created names ("4f"). */ ++ static char symbol_name_build[24]; ++ register char *p; ++ register char *q; ++ char symbol_name_temporary[20]; /* Build up a number, BACKWARDS. */ ++ ++ know (n >= 0); ++#ifdef TC_MMIX ++ know ((uint32_t) augend <= 2 /* See mmix_fb_label. */); ++#else ++ know ((uint32_t) augend <= 1); ++#endif + p = symbol_name_build; +- * p ++ = 'L'; +- * p ++ = n + '0'; /* Make into ASCII */ +- * p ++ = 1; /* ^A */ +- n = local_label_counter [ n ] + augend; +- /* version number of this local label */ +- /* +- * Next code just does sprintf( {}, "%d", n); +- * It is more elegant to do the next part recursively, but a procedure +- * call for each digit emitted is considered too costly. +- */ ++#ifdef LOCAL_LABEL_PREFIX ++ *p++ = LOCAL_LABEL_PREFIX; ++#endif ++ *p++ = 'L'; ++ ++ /* Next code just does sprintf( {}, "%d", n); */ ++ /* Label number. */ + q = symbol_name_temporary; +- for (*q++=0; n; q++) /* emits NOTHING if n starts as 0 */ ++ for (*q++ = 0, i = n; i; ++q) + { +- know(n>0); /* We expect n > 0 always */ +- *q = n % 10 + '0'; +- n /= 10; ++ *q = i % 10 + '0'; ++ i /= 10; + } +- while (( * p ++ = * -- q )) ++ while ((*p = *--q) != '\0') ++ ++p; ++ ++ *p++ = LOCAL_LABEL_CHAR; /* ^B */ ++ ++ /* Instance number. */ ++ q = symbol_name_temporary; ++ for (*q++ = 0, i = fb_label_instance (n) + augend; i; ++q) + { ++ *q = i % 10 + '0'; ++ i /= 10; + } +- /* The label, as a '\0' ended string, starts at symbol_name_build. */ ++ while ((*p++ = *--q) != '\0'); ++ ++ /* The label, as a '\0' ended string, starts at symbol_name_build. */ + return (symbol_name_build); + } + ++/* Decode name that may have been generated by foo_label_name() above. ++ If the name wasn't generated by foo_label_name(), then return it ++ unaltered. This is used for error messages. */ ++ ++char * ++decode_local_label_name (char *s) ++{ ++ char *p; ++ char *symbol_decode; ++ int label_number; ++ int instance_number; ++ char *type; ++ int index = 0; ++ ++#ifdef LOCAL_LABEL_PREFIX ++ if (s[index] == LOCAL_LABEL_PREFIX) ++ ++index; ++#endif ++ ++ if (s[index] != 'L') ++ return s; ++ ++ for (label_number = 0, p = s + index + 1; isdigit (*p); ++p) ++ label_number = (10 * label_number) + *p - '0'; ++ ++ if (*p == LOCAL_LABEL_CHAR) ++ type = "fb"; ++ else ++ return s; ++ ++ for (instance_number = 0, p++; isdigit (*p); ++p) ++ instance_number = (10 * instance_number) + *p - '0'; ++ ++#define MESSAGE_FORMAT "\"%d\" (instance number %d of a %s label)" ++ symbol_decode = obstack_alloc (¬es, strlen (MESSAGE_FORMAT) + 30); ++ sprintf (symbol_decode, MESSAGE_FORMAT, label_number, instance_number, type); ++ ++ return symbol_decode; ++} ++ + void + local_colon( + int n) /* just saw "n:" */ + { +- local_label_counter [n] ++; +- colon (local_label_name (n, 0)); ++ fb_label_instance_inc (n); ++ colon (fb_label_name (n, 0), 1); + } + + /* +@@ -184,6 +353,7 @@ + symbolP -> sy_value = value; + symbolP -> sy_frag = frag; + symbolP -> sy_prev_by_index = NULL; /* Don't know what this is yet. */ ++ symbolP -> sy_has_been_resolved = 0; + symbolP -> sy_next = NULL; /* End of chain. */ + symbolP -> sy_forward = NULL; /* JF */ + symbolP -> expression = NULL; +@@ -252,8 +422,9 @@ + + void + colon( /* just seen "x:" - rattle symbols & frags */ +-char *sym_name) /* symbol name, as a cannonical string */ ++char *sym_name, /* symbol name, as a cannonical string */ + /* We copy this string: OK to alter later. */ ++int local_colon)/* non-zero if called from local_colon() */ + { + register struct symbol * symbolP; /* symbol we are working with */ + +@@ -263,6 +434,14 @@ + as_fatal("with -n a section directive must be seen before assembly " + "can begin"); + } ++ if (inlineasm_checks && local_colon == 0) ++ { ++ if (inlineasm_file_name) ++ as_warn_where_with_column(inlineasm_file_name, inlineasm_line_number, ++ inlineasm_column_number, "label definition in inlineasm"); ++ else ++ as_bad("label definition in inlineasm"); ++ } + if ((symbolP = symbol_table_lookup( sym_name ))) + { + /* +@@ -275,7 +454,8 @@ + /* bug #50416 -O causes this not to work for: + && ((symbolP->sy_desc) & (~REFERENCE_TYPE)) == 0 + */ +- && (temp & (~(REFERENCE_TYPE | N_WEAK_REF | N_WEAK_DEF | N_ARM_THUMB_DEF | ++ && (temp & (~(REFERENCE_TYPE | N_WEAK_REF | N_WEAK_DEF | ++ N_ARM_THUMB_DEF | N_SYMBOL_RESOLVER | + N_NO_DEAD_STRIP | REFERENCED_DYNAMICALLY))) == 0 + && symbolP -> sy_value == 0) + { +@@ -285,13 +465,8 @@ + symbolP -> sy_type |= N_SECT; /* keep N_EXT bit */ + symbolP -> sy_other = frchain_now->frch_nsect; + symbolP -> sy_desc &= ~REFERENCE_TYPE; +- symbolP -> sy_desc &= ~N_WEAK_REF; ++ symbolP -> sy_desc &= ~(N_WEAK_REF & N_WEAK_DEF); + symbol_assign_index(symbolP); +- if((symbolP->sy_desc & N_WEAK_DEF) == N_WEAK_DEF && +- (frchain_now->frch_section.flags & S_COALESCED) != S_COALESCED) +- as_fatal("symbol: %s can't be a weak_definition (currently " +- "only supported in section of type coalesced)", +- sym_name); + #ifdef NeXT_MOD /* generate stabs for debugging assembly code */ + if(flagseen['g']) + make_stab_for_symbol(symbolP); +@@ -454,6 +629,52 @@ + #endif /* NeXT generate stabs for debugging assembly code */ + + /* ++ * make_subprogram_for_symbol() gathers the info that is needed for each ++ * symbol that will have a dwarf2_subprogram when generating dwarf debugging ++ * info for assembly files. ++ */ ++static ++void ++make_subprogram_for_symbol( ++symbolS *symbolP) ++{ ++ struct dwarf2_subprogram_info *i; ++ static struct dwarf2_subprogram_info *last_dwarf2_subprogram_info = NULL; ++ ++ if(symbolP->sy_name[0] == 'L') ++ return; ++ if((symbolP->sy_type & N_TYPE) != N_SECT) ++ return; ++ if(symbolP->sy_other != text_nsect) ++ return; ++ ++ i = xmalloc(sizeof(struct dwarf2_subprogram_info)); ++ i->name = symbolP->sy_name; ++ if(i->name[0] == '_') ++ i->name++; ++ i->file_number = dwarf2_file_number; ++ i->line_number = logical_input_line; ++ /* ++ * We can't used the symbolP directly as it may have the N_ARM_THUMB_DEF ++ * bit set. And that will cause the AT_high_pc and AT_low_pc values to ++ * have the low bit set after relocation producing bad dwarf. So we ++ * create a temporary symbol that will not have the N_ARM_THUMB_DEF bit ++ * set. ++ */ ++ i->symbol = symbol_temp_new(symbolP->sy_other, symbolP->sy_value, ++ symbolP->sy_frag); ++ i->next = NULL; ++ if(dwarf2_subprograms_info == NULL){ ++ dwarf2_subprograms_info = i; ++ last_dwarf2_subprogram_info = i; ++ } ++ else{ ++ last_dwarf2_subprogram_info->next = i; ++ last_dwarf2_subprogram_info = i; ++ } ++} ++ ++/* + * indirect_symbol_new() + * + * Return a pointer to a new indirect_symbol. +@@ -465,16 +686,16 @@ + indirect_symbol_new( + char *name, /* We copy this: OK to alter your copy. */ + struct frag *frag, /* For sy_frag. */ +-unsigned long offset) /* Offset from frag address. */ ++uint32_t offset) /* Offset from frag address. */ + { + isymbolS *isymbolP; + char *preserved_copy_of_name; +- unsigned long name_length; ++ uint32_t name_length; + char *p; + struct frag *fr_next; + symbolS *symbolP; + #ifdef CHECK_INDIRECTS +- unsigned long stride, fr_fix; ++ uint32_t stride, fr_fix; + #endif + + /* +@@ -528,7 +749,7 @@ + S_SYMBOL_STUBS) + stride = frchain_now->frch_section.reserved2; + else +- stride = sizeof(unsigned long); ++ stride = sizeof(uint32_t); + if(frag == frchain_now->frch_isym_last->isy_frag){ + if(offset - frchain_now->frch_isym_last->isy_offset != stride) + as_bad("missing or bad indirect symbol for section " +@@ -615,4 +836,66 @@ + + #endif /* TC_SYMFIELD_TYPE */ + ++int ++S_IS_LOCAL (symbolS *s) ++{ ++ const char *name; ++ ++ name = S_GET_NAME (s); ++ if(name == NULL) ++ return(1); ++ ++ if(name[0] == 'L' && flagseen['L'] == FALSE) ++ return(1); ++ else ++ return(0); ++} ++ ++fragS * ++symbol_get_frag (symbolS *s) ++{ ++ return(s->sy_frag); ++} ++ ++/* ++ * symbol_temp_new(), symbol_temp_new_now() are used by dwarf2dbg.c to make ++ * symbols in dwarf sections. symbol_temp_make() is used to make an undefined ++ * symbol that its values are later set by symbol_set_value_now() to the current ++ * address in a dwarf section. ++ * ++ * These are used in expressions, so the expression values can be put out in ++ * dwarf section contents. ++ */ ++symbolS * ++symbol_temp_new( ++segT nsect, ++valueT value, ++struct frag *frag) ++{ ++ return(symbol_new(FAKE_LABEL_NAME, N_SECT, nsect, 0, value, frag)); ++} ++ ++symbolS * ++symbol_temp_new_now(void) ++{ ++ return(symbol_temp_new(now_seg, frag_now_fix(), frag_now)); ++} ++ ++symbolS * ++symbol_temp_make(void) ++{ ++ return(symbol_new(FAKE_LABEL_NAME, N_UNDF, 0, 0, 0, & zero_address_frag)); ++} ++ ++/* Set the value of SYM to the current position in the current segment. */ ++void ++symbol_set_value_now( ++symbolS *sym) ++{ ++ sym->sy_type = N_SECT; ++ sym->sy_other = now_seg; ++ sym->sy_value = frag_now_fix(); ++ sym->sy_frag = frag_now; ++} ++ + /* end: symbols.c */ +Index: odcctools-9.2-ld/as/symbols.h +=================================================================== +--- odcctools-9.2-ld.orig/as/symbols.h 2013-09-03 21:08:01.409209526 +0000 ++++ odcctools-9.2-ld/as/symbols.h 2013-09-03 21:08:01.889209515 +0000 +@@ -28,9 +28,9 @@ + + extern void symbol_begin( + void); +-extern char *local_label_name( +- int n, +- int augend); ++extern char *fb_label_name( ++ int32_t n, ++ int32_t augend); + extern void + local_colon( + int n); +@@ -49,7 +49,8 @@ + extern void symbol_assign_index( + struct symbol *symbolP); + extern void colon( +- char *sym_name); ++ char *sym_name, ++ int local_colon); + extern void symbol_table_insert( + struct symbol *symbolP); + extern symbolS *symbol_find_or_make( +@@ -63,7 +64,7 @@ + extern isymbolS *indirect_symbol_new( + char *name, + struct frag *frag, +- unsigned long offset); ++ uint32_t offset); + + /* FROM line 98 */ + extern int S_IS_DEFINED (symbolS *); +@@ -80,6 +81,8 @@ + extern void S_CLEAR_EXTERNAL (symbolS *); + extern void S_SET_WEAK (symbolS *); + extern void S_SET_THREAD_LOCAL (symbolS *); ++extern int S_IS_LOCAL (symbolS *s); ++extern fragS * symbol_get_frag (symbolS *s); + + /* FROM line tc-arm.h 104 */ + #define TC_SYMFIELD_TYPE unsigned int +@@ -95,3 +98,13 @@ + extern void arm_frob_label (symbolS *); + #endif + ++extern symbolS * symbol_temp_new( ++ segT nsect, ++ valueT value, ++ struct frag *frag); ++extern symbolS * symbol_temp_new_now( ++ void); ++extern symbolS * symbol_temp_make( ++ void); ++extern void symbol_set_value_now( ++ symbolS *sym); +Index: odcctools-9.2-ld/as/Makefile.arch.in +=================================================================== +--- odcctools-9.2-ld.orig/as/Makefile.arch.in 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/as/Makefile.arch.in 2013-09-03 21:08:01.889209515 +0000 +@@ -45,7 +45,7 @@ + CFILES = app.c as.c atof-generic.c atof-ieee.c expr.c fixes.c flonum-const.c \ + flonum-copy.c flonum-mult.c frags.c hash.c hex-value.c input-file.c \ + input-scrub.c layout.c messages.c obstack.c read.c sections.c \ +- symbols.c write_object.c xmalloc.c $(CFILES_$(ARCH)) ++ symbols.c write_object.c xmalloc.c dwarf2dbg.c $(CFILES_$(ARCH)) + + OBJS = $(CFILES:.c=.o) + +Index: odcctools-9.2-ld/as/fixes.h +=================================================================== +--- odcctools-9.2-ld.orig/as/fixes.h 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/as/fixes.h 2013-09-03 21:08:01.889209515 +0000 +@@ -31,25 +31,31 @@ + */ + struct fix { + fragS *fx_frag; /* which frag? */ +- long int fx_where; /* where is the 1st byte to fix up? */ ++ int32_t fx_where; /* where is the 1st byte to fix up? */ + symbolS *fx_addsy; /* NULL or Symbol whose value we add in */ + symbolS *fx_subsy; /* NULL or Symbol whose value we subtract */ + #if defined(I386) && defined(ARCH64) + symbolS *fx_localsy; /* NULL or pseudo-symbol for this fixup */ + #endif +- long int fx_offset; /* absolute number we add in */ ++ signed_expr_t ++ fx_offset; /* absolute number we add in */ + struct fix *fx_next; /* NULL or -> next fixS */ + char fx_size; /* how many bytes are involved? */ + char fx_pcrel; /* TRUE: pc-relative. */ + char fx_pcrel_reloc;/* force a pc-relative relocatation entry */ + char fx_r_type; /* relocation type */ +- long fx_value; /* the relocated value placed in the frag */ ++ int32_t fx_value; /* the relocated value placed in the frag */ + char *file; /* the file name this came from for errors */ + unsigned int line; /* the line number this came from for errors */ + + /* FROM write.h line 82 */ + /* Has this relocation already been applied? */ +- unsigned fx_done : 1; ++ unsigned fx_done : 1, ++ ++ /* Non-zero if we have the special assembly time constant expression ++ of the difference of two symbols defined in the same section then divided ++ by exactly 2. */ ++ fx_sectdiff_divide_by_two : 1; + + /* FROM write.h line 133 */ + /* This field is sort of misnamed. It appears to be a sort of random +Index: odcctools-9.2-ld/as/read.c +=================================================================== +--- odcctools-9.2-ld.orig/as/read.c 2013-09-03 21:08:01.285209529 +0000 ++++ odcctools-9.2-ld/as/read.c 2013-09-03 21:15:08.789199489 +0000 +@@ -62,6 +62,7 @@ + #if defined(I386) && defined(ARCH64) + #include "i386.h" + #endif ++#include "dwarf2dbg.h" + + #ifdef HAVE_CONFIG_H + #include <config.h> +@@ -194,19 +195,14 @@ + *ma_hash = NULL; /* use before set up: NULL-> address error */ + static struct obstack macros; /* obstack for macro text */ + static char *macro_name = NULL; /* name of macro we are defining */ +-static struct macro_info *macro_info; /* info re. macro we are defining */ + static int count_lines = TRUE; /* turns line number counting on and off */ + static int macros_on = TRUE; /* .macros_on and .macros_off toggles this to + allow macros to be turned off, which allows + macros to override a machine instruction and + still use it. */ +-static void expand_macro(struct macro_info *info); ++static void expand_macro(char *macro_contents); + static void macro_begin(void); + +-/* iPhone binutils local: "repeat" command recording */ +-int rept_recording = 0; +-char *rept_record_start; +-int rept_times = 0; + + /* + * The .dump and .load feature is implemented with these variables and +@@ -228,10 +224,8 @@ + #ifdef PPC + static void ppcasm_pseudo_op_begin(void); + #endif +-static void pseudo_set(symbolS *symbolP); +-static void stab(int what); +-static char get_absolute_expression_and_terminator(long *val_pointer); +-static char *demand_copy_C_string(int *len_pointer); ++static void stab(uintptr_t what); ++static char get_absolute_expression_and_terminator(int32_t *val_pointer); + static char *demand_copy_string(int *lenP); + static int is_it_end_of_statement(void); + static void equals(char *sym_name); +@@ -254,7 +248,7 @@ + * for used by the machine dependent md_assemble() to create line number stabs + * for assembly instructions in the text section when -g is seen. + */ +-unsigned long text_nsect = 0; ++uint32_t text_nsect = 0; + + /* + * These are the names of the section types used by the .section directive. +@@ -279,6 +273,10 @@ + { "mod_term_funcs", S_MOD_TERM_FUNC_POINTERS }, + { "coalesced", S_COALESCED }, + { "interposing", S_INTERPOSING }, ++ { "thread_local_regular", S_THREAD_LOCAL_REGULAR }, ++ { "thread_local_variables", S_THREAD_LOCAL_VARIABLES }, ++ { "thread_local_init_function_pointers", ++ S_THREAD_LOCAL_INIT_FUNCTION_POINTERS }, + { NULL, 0 } + }; + +@@ -310,9 +308,9 @@ + char *directive; + char *segname; + char *sectname; +- unsigned long flags; /* type & attribute */ +- unsigned long default_align; +- unsigned long sizeof_stub; ++ uint32_t flags; /* type & attribute */ ++ uint32_t default_align; ++ uint32_t sizeof_stub; + }; + static const struct builtin_section builtin_sections[] = { + /* +@@ -385,6 +383,12 @@ + { "data", "__DATA", "__data" }, + { "static_data", "__DATA", "__static_data" }, + { "const_data", "__DATA", "__const" }, ++ { "tdata", "__DATA", "__thread_data", ++ S_THREAD_LOCAL_REGULAR }, ++ { "tlv", "__DATA", "__thread_vars", ++ S_THREAD_LOCAL_VARIABLES }, ++ { "thread_init_func", "__DATA", "__thread_init", ++ S_THREAD_LOCAL_INIT_FUNCTION_POINTERS }, + { "objc_class", "__OBJC", "__class", S_ATTR_NO_DEAD_STRIP }, + { "objc_meta_class", "__OBJC", "__meta_class", S_ATTR_NO_DEAD_STRIP }, + { "objc_string_object", "__OBJC", "__string_object", S_ATTR_NO_DEAD_STRIP}, +@@ -419,56 +423,56 @@ + * The routines that implement the pseudo-ops. + */ + #if !defined(I860) /* i860 has it's own align and org */ +-static void s_balign(int value); +-static void s_align(int value); +- +-static +-void +-s_align_( +-int fill_size, +-int power_of_2_alignment); +- +-static void s_org(int value); ++static void s_align(int value, int bytes_p); ++static void s_align_bytes(uintptr_t arg); ++static void s_align_ptwo(uintptr_t arg); ++static void s_org(uintptr_t value); + #endif +-static void s_private_extern(int value); ++static void s_private_extern(uintptr_t value); + #if !(defined(I386) && defined(ARCH64)) +-static void s_indirect_symbol(int value); ++static void s_indirect_symbol(uintptr_t value); + #endif +-static void s_abort(int value); +-static void s_comm(int value); +-static void s_desc(int value); +-static void s_file(int value); +-static void s_fill(int value); +-static void s_lcomm(int value); +-static void s_lsym(int value); +-static void s_set(int value); +-static void s_reference(int value); +-static void s_lazy_reference(int value); +-static void s_weak_reference(int value); +-static void s_weak_definition(int value); +-static void s_no_dead_strip(int value); +-static void s_include(int value); +-static void s_dump(int value); +-static void s_load(int value); +-static void s_if(int value); +-static void s_elseif(int value); +-static void s_else(int value); +-static void s_endif(int value); +-static void s_macros_on(int value); +-static void s_macros_off(int value); +-static void s_section(int value); +-static void s_zerofill(int value); +-static unsigned long s_builtin_section(const struct builtin_section *s); +-static void s_subsections_via_symbols(int value); +-static void s_machine(int value); +-static void s_secure_log_unique(int value); +-static void s_secure_log_reset(int value); ++static void s_abort(uintptr_t value); ++static void s_comm(uintptr_t value); ++static void s_desc(uintptr_t value); ++static void s_fill(uintptr_t value); ++static void s_lcomm(uintptr_t value); ++static void s_lsym(uintptr_t value); ++static void s_set(uintptr_t value); ++static void s_reference(uintptr_t value); ++static void s_lazy_reference(uintptr_t value); ++static void s_weak_reference(uintptr_t value); ++static void s_weak_definition(uintptr_t value); ++static void s_weak_def_can_be_hidden(uintptr_t value); ++static void s_no_dead_strip(uintptr_t value); ++static void s_symbol_resolver(uintptr_t value); ++static void s_include(uintptr_t value); ++static void s_dump(uintptr_t value); ++static void s_load(uintptr_t value); ++static void s_if(uintptr_t value); ++static void s_elseif(uintptr_t value); ++static void s_else(uintptr_t value); ++static void s_endif(uintptr_t value); ++static void s_macros_on(uintptr_t value); ++static void s_macros_off(uintptr_t value); ++static void s_section(uintptr_t value); ++static void s_zerofill(uintptr_t value); ++static uint32_t s_builtin_section(const struct builtin_section *s); ++static void s_subsections_via_symbols(uintptr_t value); ++static void s_machine(uintptr_t value); ++static void s_secure_log_unique(uintptr_t value); ++static void s_secure_log_reset(uintptr_t value); ++static void s_inlineasm(uintptr_t value); ++static void s_leb128(uintptr_t sign); ++static void s_incbin(uintptr_t value); ++static void s_data_region(uintptr_t value); ++static void s_end_data_region(uintptr_t value); + + #ifdef PPC + /* + * The routines that implement the ppcasm pseudo-ops. + */ +-static void s_ppcasm_end(int value); ++static void s_ppcasm_end(uintptr_t value); + #endif /* PPC */ + + /* +@@ -476,14 +480,14 @@ + */ + static const pseudo_typeS pseudo_table[] = { + #if !defined(I860) /* i860 has it's own align and org */ +- { "align", s_align, 1 }, +- { "align32", s_align, 4 }, +- { "balign", s_balign, 1 }, +- { "balignw", s_balign, 2 }, +- { "balignl", s_balign, 4 }, +- { "p2align", s_align, 1 }, +- { "p2alignw", s_align, 2 }, +- { "p2alignl", s_align, 4 }, ++ { "align", s_align_ptwo, 1 }, ++ { "align32", s_align_ptwo, 4 }, ++ { "p2align", s_align_ptwo, 1 }, ++ { "p2alignw", s_align_ptwo, 2 }, ++ { "p2alignl", s_align_ptwo, 4 }, ++ { "balign", s_align_bytes, 1 }, ++ { "balignw", s_align_bytes, 2 }, ++ { "balignl", s_align_bytes, 4 }, + { "org", s_org, 0 }, + #endif + #ifndef M88K /* m88k has it's own abs that uses the s_abs() in here */ +@@ -500,23 +504,26 @@ + { "comm", s_comm, 0 }, + { "desc", s_desc, 0 }, + { "double", float_cons, 'd' }, +- { "file", s_file, 0 }, ++ { "file", s_app_file, 0 }, ++ { "appfile", s_app_file, 0 }, + { "fill", s_fill, 0 }, + { "globl", s_globl, 0 }, +- { "global", s_globl, 0 }, /* iPhone binutils extension */ + { "lcomm", s_lcomm, 0 }, + { "line", s_line, 0 }, + { "long", cons, 4 }, + { "quad", cons, 8 }, + { "lsym", s_lsym, 0 }, + { "section", s_section, 0 }, +- { "zerofill", s_zerofill, 0 }, ++ { "zerofill", s_zerofill, S_ZEROFILL }, ++ { "tbss", s_zerofill, S_THREAD_LOCAL_ZEROFILL }, + { "secure_log_unique",s_secure_log_unique, 0 }, + { "secure_log_reset",s_secure_log_reset, 0 }, + { "set", s_set, 0 }, + { "short", cons, 2 }, + { "single", float_cons, 'f' }, + { "space", s_space, 0 }, ++ { "sleb128", s_leb128, 1}, ++ { "uleb128", s_leb128, 0}, + { "stabd", stab, 'd' }, + { "stabn", stab, 'n' }, + { "stabs", stab, 's' }, +@@ -525,7 +532,9 @@ + { "lazy_reference",s_lazy_reference, 0 }, + { "weak_reference",s_weak_reference, 0 }, + { "weak_definition",s_weak_definition, 0 }, ++ { "weak_def_can_be_hidden",s_weak_def_can_be_hidden, 0 }, + { "no_dead_strip",s_no_dead_strip, 0 }, ++ { "symbol_resolver",s_symbol_resolver, 0 }, + { "include", s_include, 0 }, + { "macro", s_macro, 0 }, + { "endmacro", s_endmacro, 0 }, +@@ -540,12 +549,11 @@ + { "load", s_load, 0 }, + { "subsections_via_symbols", s_subsections_via_symbols, 0 }, + { "machine", s_machine, 0 }, +- { "rept", s_rept, 0 }, +- { "endr", s_endr, 0 }, +- { "ifc", s_ifc, 0 }, +- { "ifnc", s_ifnc, 0 }, +- { "ifdef", s_ifdef, 0 }, +- { "ifndef", s_ifdef, 1 }, ++ { "inlineasmstart", s_inlineasm, 1 }, ++ { "inlineasmend", s_inlineasm, 0 }, ++ { "incbin", s_incbin, 0 }, ++ { "data_region", s_data_region, 0 }, ++ { "end_data_region", s_end_data_region, 0 }, + { NULL } /* end sentinel */ + }; + +@@ -577,7 +585,7 @@ + obstack_begin(¬es, 5000); + + #ifdef M68K /* we allow big cons only on the 68k machines */ +- bignum_low = xmalloc((long)BIGNUM_BEGIN_SIZE); ++ bignum_low = xmalloc((int32_t)BIGNUM_BEGIN_SIZE); + bignum_limit = bignum_low + BIGNUM_BEGIN_SIZE; + #endif + } +@@ -614,11 +622,12 @@ + { + const char *errtxt; + const pseudo_typeS *pop; +- unsigned long i; ++ uint32_t i; + pseudo_typeS *sections_pseudo_table; + + po_hash = hash_new(); + errtxt = NULL; ++ + for(pop = pseudo_table; + pop->poc_name && (!errtxt || *errtxt == '\0'); + pop++) +@@ -635,8 +644,8 @@ + for(i = 0; builtin_sections[i].directive != NULL; i++){ + sections_pseudo_table[i].poc_name = builtin_sections[i].directive; + sections_pseudo_table[i].poc_handler = +- (void (*)(int))s_builtin_section; +- sections_pseudo_table[i].poc_val = (int)(builtin_sections + i); ++ (void (*)(uintptr_t))s_builtin_section; ++ sections_pseudo_table[i].poc_val = (uintptr_t)(builtin_sections +i); + } + sections_pseudo_table[i].poc_name = NULL; + for(pop = (const pseudo_typeS *)sections_pseudo_table; +@@ -662,7 +671,7 @@ + const char *errtxt; + char *uppercase; + const pseudo_typeS *pop; +- unsigned long len, i; ++ uint32_t len, i; + + ppcasm_po_hash = hash_new(); + errtxt = NULL; +@@ -897,9 +906,10 @@ + used only for macro expansion */ + pseudo_typeS *pop; /* pointer to a pseudo op stucture returned by + hash_find(po_hash, s+1) to determine if it is one */ +- struct macro_info *the_macro; /* pointer to a macro name returned by ++ char *the_macro; /* pointer to a macro name returned by + hash_find(ma_hash, s) to determine if it is one */ +- int digit_value; /* the value of a digit label as an integer, 1: == 1 */ ++ int temp; /* the value of a number label as an integer, 1: == 1 */ ++ char *backup; + + /* since this is a buffer of full lines it must end in a new line */ + know(buffer_limit[-1] == '\n'); +@@ -1079,7 +1089,7 @@ + * Look for a user defined label. + */ + else if(after_name == ':'){ +- colon(s); ++ colon(s, 0); + #ifdef I860 + /* + * Intel :: feature, which makes the label global if +@@ -1123,14 +1133,6 @@ + * one to a line. + */ + else{ +- char *s2 = s; +- +- while (*s2) +- { +- *s2 = tolower(*s2); +- s2++; +- } +- + *input_line_pointer = after_name; + while(is_end_of_line(*input_line_pointer) == 0) + input_line_pointer++; +@@ -1173,24 +1175,22 @@ + continue; + } + +- /* local label ("4:") +- * iPhone binutils local - allow more than 10 local labels */ +- char *ptr = input_line_pointer - 1; +- int local_label_no = 0; +- while (isdigit(*ptr)) { +- local_label_no = local_label_no * 10 + ((*ptr) - '0'); +- ptr++; +- } +- if (*ptr == ':') { +- input_line_pointer = ptr + 1; +- local_colon(local_label_no); +- continue; +- } +- +- as_bad("Spurious digit %d.", digit_value); +- input_line_pointer--; +- ignore_rest_of_line(); +- continue; ++ /* local label ("4:") */ ++ if(isdigit(c)){ ++ backup = input_line_pointer; ++ temp = c - '0'; ++ /* Read the whole number. */ ++ while(isdigit(*input_line_pointer)) ++ { ++ temp = (temp * 10) + *input_line_pointer - '0'; ++ ++input_line_pointer; ++ } ++ if(*input_line_pointer++ == ':'){ ++ local_colon(temp); ++ continue; ++ } ++ input_line_pointer = backup; ++ } + + /* + * The only full line comment that should make it here is the first +@@ -1313,7 +1313,7 @@ + after_name = c; + after_name_pointer = input_line_pointer; + *after_name_pointer = '\0'; +- colon(s); ++ colon(s, 0); + *after_name_pointer = after_name; + /* + * A colon after the name is optional and may have a spaces +@@ -1596,7 +1596,7 @@ + static + void + s_abort( +-int value) ++uintptr_t value) + { + char *p; + +@@ -1610,6 +1610,30 @@ + + #if !defined(I860) /* i860 has it's own align and org */ + /* ++ * s_align_bytes() handles the .align pseudo-op where ".align 4" means align to ++ * a 4 byte boundary. ++ */ ++static ++void ++s_align_bytes( ++uintptr_t arg) ++{ ++ s_align(arg, 1); ++} ++ ++/* ++ * s_align_ptwo() handles the .align pseudo-op on where ".align 4" means align ++ * to a 2**4 boundary. ++ */ ++static ++void ++s_align_ptwo( ++uintptr_t arg) ++{ ++ s_align(arg, 0); ++} ++ ++/* + * s_align() implements the pseudo ops + * .align align_expression [ , 1byte_fill_expression [,max_bytes_to_fill]] + * .p2align align_expression [ , 1byte_fill_expression [,max_bytes_to_fill]] +@@ -1619,49 +1643,37 @@ + * Where align_expression is a power of 2 alignment. + * + * The parameter fill_size can only be 1, 2 or 4 which is the size of the +- * fill_expression. ++ * fill_expression. If the parameter bytes_p is non-zero the alignment value ++ * is interpreted as the byte boundary, rather than the power of 2. + */ +-static inline int32_t ilog2(uint32_t value) { +- return value == 0 ? -1 : 1 + ilog2(value >> 1); +-} +- +-static +-void +-s_balign( +-int fill_size) +-{ +- int power_of_2_alignment; +- +- if(fill_size != 1 && fill_size != 2 && fill_size != 4) +- as_bad("Internal error, s_align() called with bad fill_size %d", +- fill_size); +- +- power_of_2_alignment = get_absolute_expression(); +- power_of_2_alignment = ilog2(power_of_2_alignment); +-#define MAX_ALIGNMENT (15) +- if(power_of_2_alignment > MAX_ALIGNMENT) +- as_warn("Alignment too large: %d. assumed.", +- power_of_2_alignment = MAX_ALIGNMENT); +- else if(power_of_2_alignment < 0){ +- as_warn("Alignment negative. 0 assumed."); +- power_of_2_alignment = 0; +- } +- +- s_align_(fill_size, power_of_2_alignment); +-} +- + static + void + s_align( +-int fill_size) ++int fill_size, ++int bytes_p) + { +- int power_of_2_alignment; ++ int power_of_2_alignment, byte_alignment, i; ++ int32_t temp_fill, fill_specified, max_bytes_to_fill; ++ char fill[4]; + + if(fill_size != 1 && fill_size != 2 && fill_size != 4) + as_bad("Internal error, s_align() called with bad fill_size %d", + fill_size); + +- power_of_2_alignment = get_absolute_expression(); ++ power_of_2_alignment = 0; ++ if(bytes_p == 0){ ++ power_of_2_alignment = get_absolute_expression(); ++ } ++ else{ ++ byte_alignment = get_absolute_expression(); ++ if(byte_alignment != 0){ ++ for(i = 0; (byte_alignment & 1) == 0; i++) ++ byte_alignment >>= 1; ++ if(byte_alignment != 1) ++ as_bad("alignment not a power of 2"); ++ power_of_2_alignment = i; ++ } ++ } + #define MAX_ALIGNMENT (15) + if(power_of_2_alignment > MAX_ALIGNMENT) + as_warn("Alignment too large: %d. assumed.", +@@ -1670,19 +1682,6 @@ + as_warn("Alignment negative. 0 assumed."); + power_of_2_alignment = 0; + } +- +- s_align_(fill_size, power_of_2_alignment); +-} +- +-static +-void +-s_align_( +-int fill_size, +-int power_of_2_alignment) +-{ +- long temp_fill, fill_specified, max_bytes_to_fill; +- char fill[4]; +- + temp_fill = 0; + fill_specified = 0; + max_bytes_to_fill = 0; +@@ -1741,6 +1740,27 @@ + fill_size = 4; /* 4 byte fill size */ + } + #endif /* PPC */ ++#ifdef ARM ++ if(power_of_2_alignment >= 1){ ++ extern int thumb_mode; /* from arm.c */ ++ if(thumb_mode){ ++ if(archflag_cpusubtype == CPU_SUBTYPE_ARM_V7 || ++ archflag_cpusubtype == CPU_SUBTYPE_ARM_V7F || ++ archflag_cpusubtype == CPU_SUBTYPE_ARM_V7K){ ++ temp_fill = 0xbf00; /* thumb2 nop */ ++ fill_size = 2; /* 2 byte fill size */ ++ } ++ else{ ++ temp_fill = 0x46c0; /* thumb1 nop */ ++ fill_size = 2; /* 2 byte fill size */ ++ } ++ } ++ else if(power_of_2_alignment >= 2){ ++ temp_fill = 0xe1a00000; /* arm nop */ ++ fill_size = 4; /* 4 byte fill size */ ++ } ++ } ++#endif /* ARM */ + ; /* empty statement for other architectures */ + } + +@@ -1759,7 +1779,7 @@ + */ + if(max_bytes_to_fill == 0 && + frchain_now->frch_section.align < +- (unsigned long)power_of_2_alignment) ++ (uint32_t)power_of_2_alignment) + frchain_now->frch_section.align = power_of_2_alignment; + + demand_empty_rest_of_line(); +@@ -1773,7 +1793,7 @@ + static + void + s_comm( +-int value) ++uintptr_t value) + { + char *name; + char c; +@@ -1826,7 +1846,7 @@ + return; + } + if(symbolP->sy_value != 0){ +- if(symbolP->sy_value != (unsigned long)temp) ++ if(symbolP->sy_value != (uint32_t)temp) + as_bad("Length of .comm \"%s\" is already " TA_DFMT ". Not " + "changed to " TA_DFMT ".", symbolP->sy_name, + symbolP->sy_value, temp); +@@ -1848,7 +1868,7 @@ + static + void + s_desc( +-int value) ++uintptr_t value) + { + char *name; + char c; +@@ -1883,14 +1903,13 @@ + } + + /* +- * s_file() implements the pseudo op: ++ * s_app_file() implements the pseudo op: + * .file name [ level_number ] + * the level number is generated by /lib/cpp and is just ignored. + */ +-static + void +-s_file( +-int value) ++s_app_file( ++uintptr_t value) + { + char *s; + int length; +@@ -1931,11 +1950,11 @@ + static + void + s_fill( +-int value) ++uintptr_t value) + { +- long temp_repeat; +- long temp_size; +- long temp_fill; ++ int32_t temp_repeat; ++ int32_t temp_size; ++ int32_t temp_fill; + char *p; + + if(get_absolute_expression_and_terminator(&temp_repeat) != ','){ +@@ -1971,8 +1990,9 @@ + else if(temp_size != 0 && + temp_size != 1 && + temp_size != 2 && +- temp_size != 4){ +- as_bad(".fill size must be 0,1,2 or 4, .fill ignored"); ++ temp_size != 4 && ++ temp_size != 8){ ++ as_bad(".fill size must be 0,1,2,4 or 8, .fill ignored"); + temp_size = 0; + } + else if(temp_repeat <= 0){ +@@ -2012,11 +2032,10 @@ + /* + * s_globl() implements the pseudo op: + * .globl name [ , name ] +- * As an iPhone binutils extension, '.global' is accepted too. + */ + void + s_globl( +-int value) ++uintptr_t value) + { + char *name; + int c; +@@ -2049,7 +2068,7 @@ + static + void + s_private_extern( +-int value) ++uintptr_t value) + { + char *name; + int c; +@@ -2084,11 +2103,11 @@ + static + void + s_indirect_symbol( +-int value) ++uintptr_t value) + { + char *name; + int c; +- unsigned long section_type; ++ uint32_t section_type; + + if(!flagseen['k']) + as_fatal("incompatible feature used: .indirect_symbol (must " +@@ -2129,7 +2148,7 @@ + static + void + s_lcomm( +-int value) ++uintptr_t value) + { + char *name; + char c; +@@ -2184,7 +2203,7 @@ + bss->frch_last = bss->frch_root; + } + bss->frch_root->fr_address = round(bss->frch_root->fr_address, +- 1 << align); ++ 1 << align); + symbolP->sy_value = bss->frch_root->fr_address; + symbolP->sy_type = N_SECT; + symbolP->sy_other = bss->frch_nsect; +@@ -2194,7 +2213,7 @@ + * If this alignment is larger than any previous alignment then this + * becomes the section's alignment. + */ +- if(bss->frch_section.align < (unsigned long)align) ++ if(bss->frch_section.align < (uint32_t)align) + bss->frch_section.align = align; + } + else +@@ -2208,7 +2227,7 @@ + */ + void + s_line( +-int value) ++uintptr_t value) + { + /* + * Assume delimiter is part of expression. BSD4.2 as fails with +@@ -2232,7 +2251,7 @@ + static + void + s_lsym( +-int value) ++uintptr_t value) + { + char *name; + char c; +@@ -2293,11 +2312,11 @@ + static + void + s_org( +-int value) ++uintptr_t value) + { + segT segment; + expressionS exp; +- long temp_fill; ++ int32_t temp_fill; + char *p; + + /* +@@ -2343,7 +2362,7 @@ + static + void + s_set( +-int value) ++uintptr_t value) + { + char *name; + char delim; +@@ -2404,7 +2423,7 @@ + */ + void + s_abs( +-int value) ++uintptr_t value) + { + char *name; + char c; +@@ -2449,10 +2468,10 @@ + */ + void + s_space( +-int value) ++uintptr_t value) + { +- long temp_repeat; +- long temp_fill; ++ int32_t temp_repeat; ++ int32_t temp_fill; + char *p; + + /* Just like .fill, but temp_size = 1 */ +@@ -2480,7 +2499,7 @@ + } + + static +-unsigned long ++uint32_t + s_builtin_section( + const struct builtin_section *s) + { +@@ -2514,20 +2533,19 @@ + static + void + s_section( +-int value) ++uintptr_t value) + { + char *segname, *sectname, *typename; + char c, d, e, *p, *q, *r; + struct type_name *type_name; +- unsigned long type, attribute; ++ uint32_t type, attribute; + section_t s; + frchainS *frcP; +- unsigned long sizeof_stub; ++ uint32_t sizeof_stub; + + struct attribute_name *attribute_name; + char *attributename, *sizeof_stub_name, f, g, *t, *u, *endp; + +- SKIP_WHITESPACE(); + segname = input_line_pointer; + do{ + c = *input_line_pointer++ ; +@@ -2576,11 +2594,6 @@ + attribute_name = attribute_names; + sizeof_stub = 0; + if(d == ','){ +-#if 0 +- printf("YES optional section type\n"); +-#endif +- +- SKIP_WHITESPACE(); + typename = input_line_pointer; + do{ + e = *input_line_pointer++ ; +@@ -2602,12 +2615,7 @@ + * Now see if the optional section attribute is present. + */ + if(e == ','){ +-#if 0 +- printf("YES optional section attribute\n"); +-#endif +- + do{ +- SKIP_WHITESPACE(); + attributename = input_line_pointer; + do{ + f = *input_line_pointer++ ; +@@ -2633,7 +2641,6 @@ + */ + if(type == S_SYMBOL_STUBS){ + if(f == ','){ +- SKIP_WHITESPACE(); + sizeof_stub_name = input_line_pointer; + do{ + g = *input_line_pointer++ ; +@@ -2690,77 +2697,87 @@ + static + void + s_zerofill( +-int value) ++uintptr_t value) + { +- char *segname, *sectname, c, d, *p, *q, *name; ++ char *directive, *segname, *sectname, c, d, *p, *q, *name; + section_t s; + frchainS *frcP; + symbolS *symbolP; +- int size, align; ++ uint64_t size; ++ int align; + +- SKIP_WHITESPACE(); +- segname = input_line_pointer; +- do{ +- c = *input_line_pointer++ ; +- }while(c != ',' && c != '\0' && c != '\n' && c != ' ' && c != '\t'); +- if(c != ','){ +- as_bad("Expected comma after segment-name"); +- ignore_rest_of_line(); +- return; ++ if(value == S_THREAD_LOCAL_ZEROFILL){ ++ directive = "tbss"; ++ frcP = section_new("__DATA", "__thread_bss", value, 0, 0); ++ if(frcP->frch_root == NULL){ ++ frcP->frch_root = xmalloc(SIZEOF_STRUCT_FRAG); ++ frcP->frch_last = frcP->frch_root; ++ memset(frcP->frch_root, '\0', SIZEOF_STRUCT_FRAG); ++ } + } +- p = input_line_pointer - 1; ++ else{ ++ directive = "zerofill"; ++ segname = input_line_pointer; ++ do{ ++ c = *input_line_pointer++ ; ++ }while(c != ' ' && c != ',' && c != '\0' && c != '\n'); ++ p = input_line_pointer - 1; ++ while(c == ' '){ ++ c = *input_line_pointer++ ; ++ } ++ if(c != ','){ ++ as_bad("Expected comma after segment-name"); ++ ignore_rest_of_line(); ++ return; ++ } + +- SKIP_WHITESPACE(); +- sectname = input_line_pointer; +- do{ +- d = *input_line_pointer++ ; +- }while(d != ',' && d != '\0' && d != '\n' && c != ' ' && c != '\t'); +- if(p + 1 == input_line_pointer){ +- as_bad("Expected section-name after comma"); +- ignore_rest_of_line(); +- return; +- } +- q = input_line_pointer - 1; ++ SKIP_WHITESPACE(); ++ sectname = input_line_pointer; ++ do{ ++ d = *input_line_pointer++ ; ++ }while(d != ',' && d != '\0' && d != '\n'); ++ if(p + 1 == input_line_pointer){ ++ as_bad("Expected section-name after comma"); ++ ignore_rest_of_line(); ++ return; ++ } ++ q = input_line_pointer - 1; + +- *p = 0; +- if(strlen(segname) > sizeof(s.segname)){ +- as_bad("segment-name: %s too long (maximum %ld characters)", +- segname, sizeof(s.segname)); +- ignore_rest_of_line(); +- *p = c; +- return; +- } ++ *p = 0; ++ if(strlen(segname) > sizeof(s.segname)){ ++ as_bad("segment-name: %s too long (maximum %ld characters)", ++ segname, sizeof(s.segname)); ++ ignore_rest_of_line(); ++ *p = c; ++ return; ++ } + +- *q = 0; +- if(strlen(sectname) > sizeof(s.sectname)){ +- as_bad("section-name: %s too long (maximum %ld characters)", +- sectname, sizeof(s.sectname)); +- ignore_rest_of_line(); ++ *q = 0; ++ if(strlen(sectname) > sizeof(s.sectname)){ ++ as_bad("section-name: %s too long (maximum %ld characters)", ++ sectname, sizeof(s.sectname)); ++ ignore_rest_of_line(); ++ *p = c; ++ *q = d; ++ return; ++ } ++ ++ frcP = section_new(segname, sectname, value, 0, 0); ++ if(frcP->frch_root == NULL){ ++ frcP->frch_root = xmalloc(SIZEOF_STRUCT_FRAG); ++ frcP->frch_last = frcP->frch_root; ++ memset(frcP->frch_root, '\0', SIZEOF_STRUCT_FRAG); ++ } + *p = c; + *q = d; +- return; +- } +- +- frcP = section_new(segname, sectname, S_ZEROFILL, 0, 0); +- if(frcP->frch_root == NULL){ +- frcP->frch_root = xmalloc(SIZEOF_STRUCT_FRAG); +- frcP->frch_last = frcP->frch_root; +- memset(frcP->frch_root, '\0', SIZEOF_STRUCT_FRAG); ++ /* ++ * If this is the end of the line all that was wanted was to create ++ * the the section which is now done, so return. ++ */ ++ if(d != ',') ++ return; + } +- *p = c; +- *q = d; +- /* +- * If this is the end of the line all that was wanted was to create the +- * the section which is now done, so return. +- */ +- if(d != ',') +- return; +- +-#if 0 +- printf("YES optional extra attribute\n"); +-#endif + +- SKIP_WHITESPACE(); + if(*input_line_pointer == '"') + name = input_line_pointer + 1; + else +@@ -2774,20 +2791,14 @@ + ignore_rest_of_line(); + return; + } +- SKIP_WHITESPACE(); + input_line_pointer ++; +- if((size = get_absolute_expression()) < 0){ +- as_bad("zerofill size (%d.) <0! Ignored.", size); ++ if((int)(size = get_absolute_expression()) < 0){ ++ as_bad("%s size (%lld.) <0! Ignored.", directive, size); + ignore_rest_of_line(); + return; + } + align = 0; +- SKIP_WHITESPACE(); + if(*input_line_pointer == ','){ +-#if 0 +- printf("YES optional align attribute\n"); +-#endif +- + input_line_pointer++; + align = get_absolute_expression(); + if(align > MAX_ALIGNMENT){ +@@ -2802,7 +2813,7 @@ + * If this alignment is larger than any previous alignment then this + * becomes the section's alignment. + */ +- if(frcP->frch_section.align < (unsigned long)align) ++ if(frcP->frch_section.align < (uint32_t)align) + frcP->frch_section.align = align; + } + *p = 0; +@@ -2811,7 +2822,7 @@ + + if((symbolP->sy_type & N_TYPE) == N_UNDF && symbolP->sy_value == 0){ + frcP->frch_root->fr_address = round(frcP->frch_root->fr_address, +- 1 << align); ++ 1 << align); + symbolP->sy_value = frcP->frch_root->fr_address; + symbolP->sy_type = N_SECT | (symbolP->sy_type & (N_EXT | N_PEXT)); + symbolP->sy_other = frcP->frch_nsect; +@@ -2831,7 +2842,7 @@ + static + void + s_reference( +-int value) ++uintptr_t value) + { + char *name; + char c; +@@ -2859,7 +2870,7 @@ + static + void + s_lazy_reference( +-int value) ++uintptr_t value) + { + char *name; + char c; +@@ -2893,7 +2904,7 @@ + static + void + s_weak_reference( +-int value) ++uintptr_t value) + { + char *name; + char c; +@@ -2926,7 +2937,7 @@ + static + void + s_weak_definition( +-int value) ++uintptr_t value) + { + char *name; + char c; +@@ -2942,24 +2953,47 @@ + + *p = 0; + symbolP = symbol_find_or_make(name); +- if((symbolP->sy_type & N_TYPE) != N_UNDF && +- ((symbolP->sy_type & N_TYPE) != N_SECT || +- is_section_coalesced(symbolP->sy_other) == FALSE)) +- as_fatal("symbol: %s can't be a weak_definition (currently " +- "only supported in section of type coalesced)", name); + symbolP->sy_desc |= N_WEAK_DEF; + *p = c; + demand_empty_rest_of_line(); + } + + /* ++ * s_weak_def_can_be_hidden() implements the pseudo op: ++ * .weak_def_can_be_hidden name ++ */ ++static ++void ++s_weak_def_can_be_hidden( ++uintptr_t value) ++{ ++ char *name; ++ char c; ++ char *p; ++ symbolS *symbolP; ++ ++ if(* input_line_pointer == '"') ++ name = input_line_pointer + 1; ++ else ++ name = input_line_pointer; ++ c = get_symbol_end(); ++ p = input_line_pointer; ++ ++ *p = 0; ++ symbolP = symbol_find_or_make(name); ++ symbolP->sy_desc |= (N_WEAK_DEF | N_WEAK_REF); ++ *p = c; ++ demand_empty_rest_of_line(); ++} ++ ++/* + * s_no_dead_strip() implements the pseudo op: + * .no_dead_strip name + */ + static + void + s_no_dead_strip( +-int value) ++uintptr_t value) + { + char *name; + char c; +@@ -2981,13 +3015,41 @@ + } + + /* ++ * s_symbol_resolver() implements the pseudo op: ++ * .symbol_resolver name ++ */ ++static ++void ++s_symbol_resolver( ++uintptr_t value) ++{ ++ char *name; ++ char c; ++ char *p; ++ symbolS *symbolP; ++ ++ if(* input_line_pointer == '"') ++ name = input_line_pointer + 1; ++ else ++ name = input_line_pointer; ++ c = get_symbol_end(); ++ p = input_line_pointer; ++ ++ *p = 0; ++ symbolP = symbol_find_or_make(name); ++ symbolP->sy_desc |= N_SYMBOL_RESOLVER; ++ *p = c; ++ demand_empty_rest_of_line(); ++} ++ ++/* + * s_include() implements the pseudo op: + * .include "filename" + */ + static + void + s_include( +-int value) ++uintptr_t value) + { + char *filename; + int length; +@@ -3033,7 +3095,8 @@ + + /* we simply ignore the rest of this statement */ + void +-s_ignore (int arg ATTRIBUTE_UNUSED) ++s_ignore( ++uintptr_t arg ATTRIBUTE_UNUSED) + { + totally_ignore_line (); + } +@@ -3080,14 +3143,14 @@ + static + void + stab( +-int what) /* d == .stabd, n == .stabn, and s == .stabs */ ++uintptr_t what) /* d == .stabd, n == .stabn, and s == .stabs */ + { + symbolS *symbolP; + char *string; + int saved_type; + int length; + int goof; /* TRUE if we have aborted. */ +- long longint; ++ int32_t longint; + + saved_type = 0; + symbolP = NULL; +@@ -3128,7 +3191,7 @@ + break; + + default: +- BAD_CASE( what ); ++ BAD_CASE( (int)what ); + break; + } + if(get_absolute_expression_and_terminator(&longint) == ','){ +@@ -3190,7 +3253,6 @@ + *(old ->> May set need_pass_2 == TRUE. <<-- commented out by GNU below it + * uses symbolP->sy_forward = exp.X_add_symbol;) + */ +-static + void + pseudo_set( + symbolS *symbolP) +@@ -3232,22 +3294,36 @@ + expression = xmalloc(sizeof(expressionS)); + *expression = exp; + symbolP->expression = expression; +- + } + else{ + exp.X_add_number += exp.X_add_symbol->sy_value - + exp.X_subtract_symbol->sy_value; + } + } ++ else if(exp.X_add_symbol && ++ exp.X_subtract_symbol == NULL && ++ exp.X_add_symbol->expression != NULL){ ++ expressionS *expression; ++ ++ expression = xmalloc(sizeof(expressionS)); ++ memcpy(expression, exp.X_add_symbol->expression, ++ sizeof(expressionS)); ++ symbolP->expression = expression; ++ } + else + as_bad("Complex expression. Absolute segment assumed." ); +- /* fall through */ ++ symbolP->sy_type = N_ABS | ext; ++ symbolP->sy_other = 0; /* NO_SECT */ ++ symbolP->sy_value = exp.X_add_number; ++ symbolP->sy_frag = &zero_address_frag; ++ break; + + case SEG_ABSOLUTE: + symbolP->sy_type = N_ABS | ext; + symbolP->sy_other = 0; /* NO_SECT */ + symbolP->sy_value = exp.X_add_number; + symbolP->sy_frag = &zero_address_frag; ++ symbolP->expression = NULL; + break; + + case SEG_SECT: +@@ -3288,7 +3364,7 @@ + */ + void + cons( +-int nbytes) /* nbytes == 1 for .byte, 2 for .word, 4 for .long, 8 for .quad */ ++uintptr_t nbytes) /* nbytes == 1 for .byte, 2 for .word, 4 for .long, 8 for .quad */ + { + char c; + signed_expr_t +@@ -3299,7 +3375,11 @@ + char *p; /* points into the frag */ + segT segment; + expressionS exp; ++#ifndef TC_CONS_FIX_NEW ++ fixS *fixP; ++#endif + ++ memset(&exp, '\0', sizeof(exp)); + /* + * Input_line_pointer -> 1st char after pseudo-op-code and could legally + * be a end-of-line. (Or, less legally an eof - which we cope with.) +@@ -3349,9 +3429,9 @@ + */ + if(exp.X_add_number > 0 && + (((LITTLENUM_NUMBER_OF_BITS * exp.X_add_number) / 8) <= +- sizeof(long long))){ ++ sizeof(int64_t))){ + int i; +- long long sum; ++ int64_t sum; + + sum = 0; + for(i = 0; i < exp.X_add_number; ++i) +@@ -3363,7 +3443,7 @@ + { + as_bad("%s number illegal. Absolute 0 assumed.", + exp.X_add_number > 0 ? "Bignum" : "Floating-Point"); +- md_number_to_chars(p, (long)0, nbytes); ++ md_number_to_chars(p, (int32_t)0, nbytes); + } + break; + +@@ -3380,6 +3460,7 @@ + /* Leading bits contain both 0s & 1s. */ + as_bad("Value 0x%llx truncated to 0x%llx.", get, use); + } ++ dwarf2_emit_insn(nbytes); + /* put bytes in right order. */ + md_number_to_chars(p, use, nbytes); + break; +@@ -3393,7 +3474,7 @@ + nbytes, + &exp); + #else +- fix_new(frag_now, ++ fixP = fix_new(frag_now, + p - frag_now->fr_literal, + nbytes, + exp.X_add_symbol, +@@ -3402,6 +3483,12 @@ + 0, + 0, + 0); ++ /* ++ * If we have the special assembly time constant expression ++ * of the difference of two symbols defined in the same section ++ * then divided by exactly 2 mark the fix to indicate this. ++ */ ++ fixP->fx_sectdiff_divide_by_two = exp.X_sectdiff_divide_by_two; + #endif + break; + +@@ -3440,11 +3527,11 @@ + */ + void + big_cons( +-int nbytes) /* 8 == .quad, 16 == .octa ... */ ++uintptr_t nbytes) /* 8 == .quad, 16 == .octa ... */ + { + char c; /* input_line_pointer -> c. */ + int radix; +- long length;/* Number of chars in an object. */ ++ int32_t length;/* Number of chars in an object. */ + int digit; /* Value of 1 digit. */ + int carry; /* For multi-precision arithmetic. */ + int work; /* For multi-precision arithmetic. */ +@@ -3512,7 +3599,7 @@ + as_bad("Most significant bits truncated in integer constant."); + } + else{ +- long leading_zeroes; ++ int32_t leading_zeroes; + + for(leading_zeroes = nbytes - length; + leading_zeroes; +@@ -3547,7 +3634,7 @@ + grow_bignum( + void) + { +- long length; ++ int32_t length; + + bignum_high++; + if(bignum_high >= bignum_limit) +@@ -3582,7 +3669,7 @@ + */ + void + float_cons( +-int float_type) /* 'f':.ffloat ... 'F':.float ... */ ++uintptr_t float_type) /* 'f':.ffloat ... 'F':.float ... */ + { + char *p; + char c; +@@ -3637,6 +3724,129 @@ + demand_empty_rest_of_line(); + } + ++static void ++emit_leb128_expr (expressionS *exp, int sign) ++{ ++ segT op = exp->X_op; ++#ifdef notyet ++ unsigned int nbytes; ++#endif ++ ++ if (op == O_absent) ++ { ++ as_warn (_("zero assumed for missing expression")); ++ exp->X_add_number = 0; ++ op = O_constant; ++ } ++ else if (op == O_big && exp->X_add_number <= 0) ++ { ++ as_bad (_("floating point number invalid")); ++ exp->X_add_number = 0; ++ op = O_constant; ++ } ++#ifdef notyet ++ else if (op == O_register) ++ { ++ as_warn (_("register value used as expression")); ++ op = O_constant; ++ } ++ else if (op == O_constant ++ && sign ++ && (exp->X_add_number < 0) != !exp->X_unsigned) ++ { ++ /* We're outputting a signed leb128 and the sign of X_add_number ++ doesn't reflect the sign of the original value. Convert EXP ++ to a correctly-extended bignum instead. */ ++ convert_to_bignum (exp); ++ op = O_big; ++ } ++ ++ /* Let check_eh_frame know that data is being emitted. nbytes == -1 is ++ a signal that this is leb128 data. It shouldn't optimize this away. */ ++ nbytes = (unsigned int) -1; ++ if (check_eh_frame (exp, &nbytes)) ++ abort (); ++ ++ /* Let the backend know that subsequent data may be byte aligned. */ ++#ifdef md_cons_align ++ md_cons_align (1); ++#endif ++#endif /* notyet */ ++ ++ if (op == O_constant) ++ { ++ /* If we've got a constant, emit the thing directly right now. */ ++ ++ valueT value = exp->X_add_number; ++ int size; ++ char *p; ++ ++ size = sizeof_leb128 (value, sign); ++ p = frag_more (size); ++ output_leb128 (p, value, sign); ++ } ++#ifdef notyet ++ else if (op == O_big) ++ { ++ /* O_big is a different sort of constant. */ ++ ++ int size; ++ char *p; ++ ++ size = output_big_leb128 (NULL, generic_bignum, exp->X_add_number, sign); ++ p = frag_more (size); ++ output_big_leb128 (p, generic_bignum, exp->X_add_number, sign); ++ } ++#endif /* notyet */ ++ else ++ { ++ /* Otherwise, we have to create a variable sized fragment and ++ resolve things later. */ ++ ++#ifdef OLD ++ frag_var (rs_leb128, sizeof_uleb128 (~(valueT) 0), 0, sign, ++ make_expr_symbol (exp), 0, (char *) NULL); ++#else ++ symbolS *sym; ++ expressionS *expression; ++ ++ sym = symbol_temp_new(exp->X_add_symbol->sy_other /* GUESS */, 0, NULL); ++ expression = xmalloc(sizeof(expressionS)); ++ *expression = *exp; ++ sym->expression = expression; ++ sym->sy_frag = &zero_address_frag; ++ frag_var (rs_leb128, sizeof_leb128 ( ((valueT) (~(valueT) 0) >> 1), 0), 0, sign, ++ sym, 0, (char *) NULL); ++ frchain_now->has_rs_leb128s = TRUE; ++#endif ++ ++ } ++} ++ ++/* Parse the .sleb128 and .uleb128 pseudos. */ ++ ++static ++void ++s_leb128( ++uintptr_t sign) ++{ ++ expressionS exp; ++ ++#ifdef md_flush_pending_output ++ md_flush_pending_output (); ++#endif ++ ++ do ++ { ++ expression (&exp); ++ emit_leb128_expr (&exp, sign); ++ } ++ while (*input_line_pointer++ == ','); ++ ++ input_line_pointer--; ++ demand_empty_rest_of_line (); ++} ++ + /* + * stringer() + * +@@ -3647,7 +3857,7 @@ + */ + void + stringer( +-int append_zero) /* 0: don't append '\0', else 1 */ ++uintptr_t append_zero) /* 0: don't append '\0', else 1 */ + { + int c; + +@@ -3699,7 +3909,7 @@ + void) + { + int c; +- long number, i; ++ int32_t number, i; + + c = *input_line_pointer++; + /* make sure the 0xff char is not returned as -1 */ +@@ -3866,7 +4076,7 @@ + static + char /* return terminator */ + get_absolute_expression_and_terminator( +-long *val_pointer) /* return value of expression */ ++int32_t *val_pointer) /* return value of expression */ + { + *val_pointer = get_absolute_expression(); + return(*input_line_pointer++); +@@ -3878,7 +4088,6 @@ + * Like demand_copy_string, but return NULL if the string contains any '\0's. + * Give a warning if that happens. + */ +-static + char * + demand_copy_C_string( + int *len_pointer) +@@ -3899,16 +4108,6 @@ + return(s); + } + +-static int is_identifier_char(char c) { +- return +- (c >= 'a' && c <= 'z') || +- (c >= 'A' && c <= 'Z') || +- (c >= '0' && c <= '9') || +- (c == '_' || c == '.') || +- (c == '=' || c == '$') || +- (c == '#'); +-} +- + /* + * demand_copy_string() + * +@@ -3935,23 +4134,22 @@ + { + input_line_pointer++; /* Skip opening quote. */ + while((c = next_char_of_string()) >= 0){ +- obstack_1grow(¬es, c); ++ (void)(obstack_1grow(¬es, c)); + len++; + } ++ /* ++ * This next line is so demand_copy_C_string will return a null ++ * termanated string. ++ */ ++ (void)(obstack_1grow(¬es, '\0')); ++ retval = obstack_finish(¬es); + } + else{ +- while (is_identifier_char(*input_line_pointer)) { +- obstack_1grow(¬es, *input_line_pointer++); +- len++; +- } ++ as_bad("Missing string"); ++ retval = NULL; ++ ignore_rest_of_line(); + } +- /* +- * This next line is so demand_copy_C_string will return a null +- * termanated string. +- */ +- obstack_1grow(¬es, '\0'); + *lenP = len; +- retval = obstack_finish(¬es); + return(retval); + } + +@@ -4031,7 +4229,7 @@ + static + void + s_if( +-int value) ++uintptr_t value) + { + if(if_depth >= MAX_IF_DEPTH) + as_fatal("You can't nest if's more than %d levels deep", +@@ -4047,105 +4245,6 @@ + } + } + +-/* iPhone binutils extension: .ifc assembles if the two strings are the same */ +-void s_ifnc(int value) +-{ +- char *ptr1, *ptr2; +- int len1, len2; +- +- if (if_depth >= MAX_IF_DEPTH) +- as_fatal("Maximum if nesting level reached"); +- last_states[if_depth++] = the_cond_state; +- the_cond_state.the_cond = if_cond; +- +- if (the_cond_state.ignore) +- totally_ignore_line(); +- else { +- ptr1 = demand_copy_string(&len1); +- +- SKIP_WHITESPACE(); +- if (*input_line_pointer != ',') +- as_bad(".ifnc needs two strings separated by a comma (',')"); +- else +- input_line_pointer++; +- +- ptr2 = demand_copy_string(&len2); +- +- the_cond_state.cond_met = (len1 != len2 || strncmp(ptr1, ptr2, len1)); +- the_cond_state.ignore = !the_cond_state.cond_met; +- demand_empty_rest_of_line(); +- } +-} +- +-/* iPhone binutils extension: .ifc assembles if the two strings are the same */ +-void s_ifc(int value) +-{ +- char *ptr1, *ptr2; +- int len1, len2; +- +- if (if_depth >= MAX_IF_DEPTH) +- as_fatal("Maximum if nesting level reached"); +- last_states[if_depth++] = the_cond_state; +- the_cond_state.the_cond = if_cond; +- +- if (the_cond_state.ignore) +- totally_ignore_line(); +- else { +- ptr1 = demand_copy_string(&len1); +- +- SKIP_WHITESPACE(); +- if (*input_line_pointer != ',') +- as_bad(".ifc needs two strings separated by a comma (',')"); +- else +- input_line_pointer++; +- +- ptr2 = demand_copy_string(&len2); +- +- the_cond_state.cond_met = (len1 == len2 && !strncmp(ptr1, ptr2, len1)); +- the_cond_state.ignore = !the_cond_state.cond_met; +- demand_empty_rest_of_line(); +- } +-} +- +-/* iPhone binutils extension: .ifdef assembles if the given symbol is defined. */ +-void s_ifdef(int value) +-{ +- /* Points to name of symbol. */ +- char *name; +- /* Points to symbol. */ +- symbolS *symbolP; +- char c; +- +- if (if_depth >= MAX_IF_DEPTH) +- as_fatal("Maximum if nesting level reached"); +- last_states[if_depth++] = the_cond_state; +- the_cond_state.the_cond = if_cond; +- +- if (the_cond_state.ignore) +- totally_ignore_line(); +- else { +- /* Leading whitespace is part of operand. */ +- SKIP_WHITESPACE (); +- name = input_line_pointer; +- +- if (!is_name_beginner (*name)) +- { +- as_bad (_("invalid identifier for \".ifdef\"")); +- ignore_rest_of_line (); +- return; +- } +- +- c = get_symbol_end (); +- symbolP = symbol_find (name); +- *input_line_pointer = c; +- +- the_cond_state.cond_met = (value == 0) == (symbolP != NULL && S_IS_DEFINED (symbolP)); +- the_cond_state.ignore = !the_cond_state.cond_met; +- +- demand_empty_rest_of_line (); +- } +-} +- + /* + * s_elseif() implements the pseudo op: + * .elseif expression +@@ -4154,7 +4253,7 @@ + static + void + s_elseif( +-int value) ++uintptr_t value) + { + int last_ignore_state; + +@@ -4186,7 +4285,7 @@ + static + void + s_else( +-int value) ++uintptr_t value) + { + int last_ignore_state; + +@@ -4213,7 +4312,7 @@ + static + void + s_endif( +-int value) ++uintptr_t value) + { + if((the_cond_state.the_cond == no_cond) || (if_depth == 0)) + as_fatal("Encountered a .endif that doesn't follow a .if or .else"); +@@ -4245,7 +4344,7 @@ + static + void + s_macros_on( +-int value) ++uintptr_t value) + { + macros_on = TRUE; + demand_empty_rest_of_line(); +@@ -4257,106 +4356,34 @@ + */ + void + s_macros_off( +-int value) ++uintptr_t value) + { + macros_on = FALSE; + demand_empty_rest_of_line(); + } + +-int is_eol(char c) +-{ +- return (c == '\r' || c == '\n' || c == '\0'); +-} +- +-int is_ignorable_ws(char c) +-{ +- return (c == ' ' || c == '\t'); +-} +- + /* + * s_macro() implements the pseudo op: + * .macro macro_name + * that defines a macro. +- * +- * iPhone binutils local: support the GAS 2.17-style macro definitions + */ + void + s_macro( +-int value) ++uintptr_t value) + { +- char *ptr; +- int len; +- struct macro_arg *arg; ++ int c; ++ pseudo_typeS *pop; + + if(macro_name) + as_bad("Can't define a macro inside another macro definition"); + else{ +- while (is_ignorable_ws(*input_line_pointer)) +- input_line_pointer++; +- ptr = input_line_pointer; +- while (is_part_of_name(*input_line_pointer)) +- input_line_pointer++; +- len = input_line_pointer - ptr; +- macro_name = malloc(len + 1); +- strncpy(macro_name, ptr, len); +- macro_name[len] = '\0'; +- +- macro_info = (struct macro_info *)malloc(sizeof(struct macro_info)); +- macro_info->name = macro_name; +- macro_info->contents = NULL; +- macro_info->arg_count = 0; +- macro_info->args = (struct macro_arg **)malloc(sizeof(struct macro_arg +- *) * 32); /* TODO: don't have a hard arg limit */ +- +- /* Grab the arguments. */ +- while (1) { +- while (is_ignorable_ws(*input_line_pointer) || *input_line_pointer +- == ',') +- input_line_pointer++; +- ptr = input_line_pointer; +- while (is_part_of_name(*input_line_pointer) || *input_line_pointer +- == '=') +- input_line_pointer++; +- len = input_line_pointer - ptr; +- +- if (len <= 0) +- break; +- +- arg = (struct macro_arg *)malloc(sizeof(struct macro_arg)); +- arg->name = malloc(len + 1); +- strncpy(arg->name, ptr, len); +- arg->name[len] = '\0'; +- arg->default_value = arg->name; +- strsep(&(arg->default_value), "="); +- +- if (!(arg->default_value)) +- arg->default_value = ""; +- +- macro_info->args[(macro_info->arg_count)++] = arg; +- } +- +- macro_info->new_style = macro_info->arg_count > 0; +- +-#if 0 +- printf("macro %s:\n", macro_info->name); +- int i; +- for (i = 0; i < macro_info->arg_count; i++) +- printf("arg %d: name %s, default %s\n", i, +- macro_info->args[i]->name, macro_info->args[i]->default_value); +-#endif +- +-#if 0 +- int c; +- pseudo_typeS *pop; +- +- *input_line_pointer++; +- ++ SKIP_WHITESPACE(); + while(is_part_of_name(c = *input_line_pointer ++)) +- obstack_1grow (¯os, c); +- obstack_1grow(¯os, '\0'); ++ (void)(obstack_1grow (¯os, c)); ++ (void)(obstack_1grow(¯os, '\0')); + --input_line_pointer; + macro_name = obstack_finish(¯os); +- if(macro_name == "") ++ if(macro_name == NULL) + as_bad("Missing name of macro"); + if(*macro_name == '.'){ + pop = (pseudo_typeS *)hash_find(po_hash, macro_name + 1); +@@ -4364,9 +4391,7 @@ + as_bad("Pseudo-op name: %s can't be a macro name", + macro_name); + } +-#endif + } +- + totally_ignore_line(); + } + +@@ -4377,7 +4402,7 @@ + */ + void + s_endmacro( +-int value) ++uintptr_t value) + { + const char *errorString; + +@@ -4386,83 +4411,16 @@ + ignore_rest_of_line(); + } + else{ +- obstack_1grow(¯os, '\0'); +- +- macro_info->contents = obstack_finish(¯os); +- +- errorString = hash_insert(ma_hash, macro_name, macro_info); ++ (void)(obstack_1grow(¯os, '\0')); ++ errorString = hash_insert(ma_hash, macro_name, ++ obstack_finish(¯os)); + if(errorString != NULL && *errorString) +- as_bad("The macro named \"%s\" is already defined", ++ as_warn("The macro named \"%s\" is already defined", + macro_name); + macro_name = NULL; + } + } + +-void s_rept(int value) +-{ +- if (rept_recording) +- as_bad("Nested repetition ('.rept') isn't allowed"); +- else { +- rept_times = strtol(input_line_pointer, &input_line_pointer, 10); +- +- rept_recording = 1; +- rept_record_start = input_line_pointer; +- } +- +- totally_ignore_line(); +-} +- +-void s_endr(int value) +-{ +- char *buffer, *last_buffer_limit, *last_input_line_pointer, *new_buf, *ptr; +- int i, last_count_lines, len; +- +- if (!rept_recording) { +- as_bad("'.endr' found, but I wasn't instructed to repeat anything"); +- return; +- } +- +- ptr = input_line_pointer; +- while (*ptr != '.') +- ptr--; /* back up to before this op so it isn't parsed */ +- ptr--; +- +- len = ptr - rept_record_start; +- new_buf = malloc(len + 2); +- strncpy(new_buf, rept_record_start, len); +- new_buf[len] = '\n'; +- new_buf[len+1] = '\0'; +- +-#if 0 +- printf("new buf is: %s\n", new_buf); +-#endif +- +- last_buffer_limit = buffer_limit; +- last_count_lines = count_lines; +- last_input_line_pointer = input_line_pointer; +- +- /* Note: we start at 1 because one instance will have already been +- * assembled at this point. */ +- for (i = 1; i < rept_times; i++) { +- buffer_limit = new_buf + len + 1; +- buffer = new_buf; +- count_lines = FALSE; +- +- #ifdef PPC +- if(flagseen[(int)'p'] == TRUE) +- ppcasm_parse_a_buffer(buffer); +- else +- #endif /* PPC */ +- parse_a_buffer(buffer); +- } +- +- buffer_limit = last_buffer_limit; +- count_lines = last_count_lines; +- input_line_pointer = last_input_line_pointer; +- +- rept_recording = 0; +-} +- + /* + * macro_begin() initializes macros. + */ +@@ -4488,7 +4446,7 @@ + do{ + c = *char_pointer ++; + know(c != '\0'); +- obstack_1grow(¯os, c); ++ (void)(obstack_1grow(¯os, c)); + }while((c != ':') && !(is_end_of_line(c))); + if(char_pointer > input_line_pointer) + input_line_pointer = char_pointer; +@@ -4496,27 +4454,20 @@ + + /* + * expand_macro() is called to expand macros. +- * +- * iPhone binutils local: lots of additions to deal with GAS 2.17-style macros. + */ + static + void + expand_macro( +-struct macro_info *info) ++char *macro_contents) + { +- char *macro_contents; + char *buffer; +- char *ptr, *arg_buf, *arg_val_ptr; + char c; + int index, nargs; + char *last_buffer_limit; + int last_count_lines; +- int named_invocation, len, i, which_arg; + char *last_input_line_pointer; + char *arguments [10]; /* at most 10 arguments, each is substituted */ + +- macro_contents = info->contents; +- + if(macro_depth >= MAX_MACRO_DEPTH) + as_fatal("You can't nest macros more than %d levels deep", + MAX_MACRO_DEPTH); +@@ -4524,198 +4475,80 @@ + + /* copy each argument to a object in the macro obstack */ + nargs = 0; +- +- memset(arguments, '\0', sizeof(char *) * 10); +- +- /* iPhone binutils new: parse new-style arguments */ +- if (info->new_style) { +- /* First, determine if it's a named-argument style invocation or a +- * normal invocation. The presence of '=' should be good enough to +- * determine which it is. */ +- named_invocation = 0; +- ptr = input_line_pointer; +- while (is_identifier_char(*ptr)) { +- if (*ptr == '=') { +- named_invocation = 1; +- break; +- } +- ptr++; +- } +- +- index = 0; +- +- SKIP_WHITESPACE(); +- +- /* Ok, now parse each argument. */ +- while (1) { +- int length; +- char *value = demand_copy_string(&length); +- +- if (named_invocation) { +- if (*input_line_pointer++ != '=') { +- as_bad("In a named-argument-style macro invocation, " +- "all of the arguments must be specified in the " +- "named-argument style, but one or more weren't"); +- break; +- } +- +- /* We've parsed it fine, now just find which argument the +- * user meant. */ +- which_arg = -1; +- for (i = 0; i < info->arg_count; i++) { +- if (!strcmp(value, info->args[i]->name)) { +- which_arg = i; +- break; +- } +- } +- +- if (which_arg == -1) { +- as_bad("'%s' doesn't name an argument of the macro " +- "'%s'", arg_buf, info->name); +- break; +- } +- +- arguments[which_arg] = demand_copy_string(&length); +- } else { +- /* If not a named invocation, it's simple. */ +- arguments[index++] = value; +- } +- +- if (*input_line_pointer == ',') { +- ++input_line_pointer; +- SKIP_WHITESPACE(); +- continue; +- } else if ( +- !is_end_of_line(*input_line_pointer) && +- !is_ignorable_ws(*input_line_pointer) +- ) { +- as_bad("invalid macro expansion argument character (%c)", *input_line_pointer); +- } +- +- SKIP_WHITESPACE(); +- +- if (is_end_of_line(*input_line_pointer)) +- break; +- } +- +- nargs = info->arg_count; +- +- /* Fill in blank args with default values. */ +- for (i = 0; i < nargs; i++) +- if (arguments[i] == NULL || arguments[i][0] == '\0') +- arguments[i] = info->args[i]->default_value; +- } else { +- /* Fall back to the old-style arguments - note that it doesn't matter +- * which we use for a zero-argument macro. */ +- for(index = 0; index < 10; index ++){ +- if(*input_line_pointer == ' ') +- ++input_line_pointer; +- know(*input_line_pointer != ' '); +- c = *input_line_pointer; +- if(is_end_of_line(c)) +- arguments[index] = NULL; +- else{ +- int parenthesis_depth = 0; +- do{ +- c = *input_line_pointer++; +- if(parenthesis_depth){ +- if(c == ')') +- parenthesis_depth --; +- } +- else{ +- if(c == '(') +- parenthesis_depth ++; +- else +- if(is_end_of_line(c) || +- (c == ' ') || (c == ',')) +- break; +- } +- know(c != '\0'); +- if(is_end_of_line(c)) +- as_bad("mismatched parenthesis"); +- obstack_1grow(¯os, c); +- }while(1); +- obstack_1grow(¯os, '\0'); +- arguments[index] = obstack_finish(¯os); +- nargs++; +- if(is_end_of_line(c)) +- --input_line_pointer; +- else if(c == ' ') +- if(*input_line_pointer == ',') +- input_line_pointer++; +- } +- } +- if(!is_end_of_line(c)){ +- as_bad("More than 10 arguments not allowed for macros"); +- ignore_rest_of_line(); +- } +- } ++ for(index = 0; index < 10; index ++){ ++ if(*input_line_pointer == ' ') ++ ++input_line_pointer; ++ know(*input_line_pointer != ' '); ++ c = *input_line_pointer; ++ if(is_end_of_line(c)) ++ arguments[index] = NULL; ++ else{ ++ int parenthesis_depth = 0; ++ do{ ++ SKIP_WHITESPACE(); ++ c = *input_line_pointer++; ++ if(parenthesis_depth){ ++ if(c == ')') ++ parenthesis_depth --; ++ } ++ else{ ++ if(c == '(') ++ parenthesis_depth ++; ++ else ++ if(is_end_of_line(c) || ++ (c == ' ') || (c == ',')) ++ break; ++ } ++ know(c != '\0'); ++ if(is_end_of_line(c)) ++ as_bad("mismatched parenthesis"); ++ (void)(obstack_1grow(¯os, c)); ++ }while(1); ++ (void)(obstack_1grow(¯os, '\0')); ++ arguments[index] = obstack_finish(¯os); ++ nargs++; ++ if(is_end_of_line(c)) ++ --input_line_pointer; ++ else if(c == ' ') ++ if(*input_line_pointer == ',') ++ input_line_pointer++; ++ } ++ } ++ if(!is_end_of_line(c)){ ++ as_bad("More than 10 arguments not allowed for macros"); ++ ignore_rest_of_line(); ++ } + /* + * Build a buffer containing the macro contents with arguments + * substituted + */ +- obstack_1grow(¯os, '\n'); +- +- while((c = *macro_contents++)){ +- if (c == '\\') { +- if (*macro_contents == '\\') +- macro_contents++; +- else { +- ptr = macro_contents; +- while (is_part_of_name(*ptr)) +- ptr++; +- +- index = -1; +- for (i = 0; i < info->arg_count; i++) { +- if (!strncmp(macro_contents, info->args[i]->name, +- ptr - macro_contents)) { +- index = i; +- break; +- } +- } +- +- macro_contents = ptr; +- +- if (index == -1) +- as_bad("Undeclared macro argument"); +- else { +- last_input_line_pointer = macro_contents; +- macro_contents = arguments[index]; +- if (macro_contents) { +- while ((c = *(macro_contents++))) +- obstack_1grow(¯os, c); +- } +- macro_contents = last_input_line_pointer; +- continue; +- } +- } +- } +- else if(c == '$'){ +- if(*macro_contents == '$'){ +- macro_contents++; +- } +- else if((*macro_contents >= '0') && (*macro_contents <= '9')){ +- index = *macro_contents++ - '0'; +- last_input_line_pointer = macro_contents; +- macro_contents = arguments[index]; +- if(macro_contents){ +- while ((c = * macro_contents ++)) +- obstack_1grow (¯os, c); +- } +- macro_contents = last_input_line_pointer; +- continue; +- } +- else if (*macro_contents == 'n'){ +- macro_contents++ ; +- obstack_1grow(¯os, nargs + '0'); +- continue; +- } +- } +- obstack_1grow (¯os, c); +- } +- +- obstack_1grow (¯os, '\n'); +- obstack_1grow (¯os, '\0'); ++ (void)(obstack_1grow(¯os, '\n')); ++ while((c = *macro_contents++)){ ++ if(c == '$'){ ++ if(*macro_contents == '$'){ ++ macro_contents++; ++ } ++ else if((*macro_contents >= '0') && (*macro_contents <= '9')){ ++ index = *macro_contents++ - '0'; ++ last_input_line_pointer = macro_contents; ++ macro_contents = arguments[index]; ++ if(macro_contents){ ++ while ((c = * macro_contents ++)) ++ (void)(obstack_1grow (¯os, c)); ++ } ++ macro_contents = last_input_line_pointer; ++ continue; ++ } ++ else if (*macro_contents == 'n'){ ++ macro_contents++ ; ++ (void)(obstack_1grow(¯os, nargs + '0')); ++ continue; ++ } ++ } ++ (void)(obstack_1grow (¯os, c)); ++ } ++ (void)(obstack_1grow (¯os, '\n')); ++ (void)(obstack_1grow (¯os, '\0')); + last_buffer_limit = buffer_limit; + last_count_lines = count_lines; + last_input_line_pointer = input_line_pointer; +@@ -4732,13 +4565,9 @@ + #endif /* PPC */ + parse_a_buffer(buffer + 1); + obstack_free (¯os, buffer); +- +- if (!(info->new_style)) { +- for(index = 9; index >= 0; index --) +- if(arguments[index]) +- obstack_free(¯os, arguments[index]); +- } +- ++ for(index = 9; index >= 0; index --) ++ if(arguments[index]) ++ obstack_free(¯os, arguments[index]); + buffer_limit = last_buffer_limit; + count_lines = last_count_lines; + input_line_pointer = last_input_line_pointer; +@@ -4753,7 +4582,7 @@ + static + void + s_dump( +-int value) ++uintptr_t value) + { + char *filename; + int length; +@@ -4821,7 +4650,7 @@ + static + void + s_load( +-int value) ++uintptr_t value) + { + char *char_pointer; + char *filename; +@@ -4837,14 +4666,14 @@ + do{ + do{ + the_char = getc_unlocked(dump_fp); +- obstack_1grow(¯os, the_char); ++ (void)(obstack_1grow(¯os, the_char)); + }while(the_char); + char_pointer = obstack_finish (¯os); + if(!(*char_pointer)) + break; + do{ + the_char = getc_unlocked(dump_fp); +- obstack_1grow(¯os, the_char); ++ (void)(obstack_1grow(¯os, the_char)); + }while(the_char); + if(hash_insert(ma_hash, char_pointer, + obstack_finish(¯os))) +@@ -4861,7 +4690,7 @@ + do{ + do{ + the_char = getc_unlocked(dump_fp); +- obstack_1grow(¯os, the_char); ++ (void)(obstack_1grow(¯os, the_char)); + }while(the_char); + char_pointer = obstack_base(¯os); + obstack_next_free(¯os) = char_pointer; +@@ -4895,7 +4724,7 @@ + static + void + s_subsections_via_symbols( +-int value) ++uintptr_t value) + { + demand_empty_rest_of_line(); + subsections_via_symbols = TRUE; +@@ -4910,11 +4739,12 @@ + static + void + s_machine( +-int value) ++uintptr_t value) + { + char *arch_name, c; + struct arch_flag arch_flag; + cpu_subtype_t new_cpusubtype; ++ const struct arch_flag *family_arch_flag; + + arch_name = input_line_pointer; + /* +@@ -4926,26 +4756,32 @@ + *--input_line_pointer = 0; + + if(force_cpusubtype_ALL == FALSE){ +- if(get_arch_from_flag(arch_name, &arch_flag) == 0){ ++ family_arch_flag = NULL; ++ if(strcmp(arch_name, "all") == 0){ ++ family_arch_flag = get_arch_family_from_cputype(md_cputype); ++ if(family_arch_flag != NULL) ++ arch_flag = *family_arch_flag; ++ } ++ if(family_arch_flag == NULL && ++ get_arch_from_flag(arch_name, &arch_flag) == 0){ + as_bad("unknown .machine argument: %s", arch_name); ++ return; ++ } ++ if(arch_flag.cputype != md_cputype){ ++ as_bad("invalid .machine argument: %s", arch_name); + } + else{ +- if(arch_flag.cputype != md_cputype){ +- as_bad("invalid .machine argument: %s", arch_name); ++ new_cpusubtype = cpusubtype_combine(md_cputype, ++ md_cpusubtype, ++ arch_flag.cpusubtype); ++ if(new_cpusubtype == -1){ ++ as_bad(".machine argument: %s can not be combined " ++ "with previous .machine directives, -arch " ++ "arguments or machine specific instructions", ++ arch_name); + } + else{ +- new_cpusubtype = cpusubtype_combine(md_cputype, +- md_cpusubtype, +- arch_flag.cpusubtype); +- if(new_cpusubtype == -1){ +- as_bad(".machine argument: %s can not be combined " +- "with previous .machine directives, -arch " +- "arguments or machine specific instructions", +- arch_name); +- } +- else{ +- archflag_cpusubtype = new_cpusubtype; +- } ++ archflag_cpusubtype = new_cpusubtype; + } + } + } +@@ -4964,7 +4800,7 @@ + static + void + s_secure_log_reset( +-int value) ++uintptr_t value) + { + s_secure_log_used = FALSE; + demand_empty_rest_of_line(); +@@ -4982,7 +4818,7 @@ + static + void + s_secure_log_unique( +-int value) ++uintptr_t value) + { + FILE *secure_log_fp; + char *log_msg, c; +@@ -5021,6 +4857,127 @@ + demand_empty_rest_of_line(); + } + ++/* ++ * When inlineasm_checks is non-zero, then these variable are set and used ++ * when reporting errors for the properties of GCC function-scope inline asms. ++ */ ++int inlineasm_checks = 0; ++char *inlineasm_file_name = NULL; ++int inlineasm_line_number = 0; ++int inlineasm_column_number = 0; ++ ++/* ++ * s_inlineasm() handles the pseudo ops: ++ * .inlineasmstart [[["file_name"] [,<line_number>]] [,<column_number>]] ++ * .inlineasmend ++ * The parameter value is 1 for start and 0 for end. The arguments to the ++ * start directive are optional. ++ * ++ * This causes the assembler enforces properties required of GCC function-scope ++ * inline asms. ++ * ++ * The requirement that does not allow non-numeric labels to be defined in an ++ * inline asm is checked for in colon(). ++ */ ++static ++void ++s_inlineasm( ++uintptr_t value) ++{ ++ int length; ++ ++ inlineasm_checks = value; ++ inlineasm_file_name = NULL; ++ inlineasm_line_number = 0; ++ inlineasm_column_number = 0; ++ ++ SKIP_WHITESPACE(); ++ if(value == 1 && *input_line_pointer == '"'){ ++ if((inlineasm_file_name = demand_copy_string(&length))){ ++ SKIP_WHITESPACE(); ++ if(*input_line_pointer == ','){ ++ input_line_pointer++; ++ inlineasm_line_number = get_absolute_expression(); ++ SKIP_WHITESPACE(); ++ if(*input_line_pointer == ','){ ++ input_line_pointer++; ++ inlineasm_column_number = get_absolute_expression(); ++ } ++ } ++ } ++ } ++ demand_empty_rest_of_line(); ++} ++ ++/* ++ * s_incbin() implements the pseudo op: ++ * .incbin "filename" ++ */ ++static ++void ++s_incbin( ++uintptr_t value) ++{ ++ char *filename, *whole_file_name, *p; ++ int length; ++ FILE *fp; ++ int the_char; ++ ++ /* Some assemblers tolerate immediately following '"' */ ++ if((filename = demand_copy_string( & length ) )) { ++ demand_empty_rest_of_line(); ++ whole_file_name = find_an_include_file(filename); ++ if(whole_file_name != NULL && ++ (fp = fopen(whole_file_name, "r"))){ ++ do{ ++ the_char = getc_unlocked(fp); ++ if (the_char != -1){ ++ p = frag_more(1); ++ *p = the_char; ++ } ++ }while(the_char != -1); ++ fclose(fp); ++ return; ++ } ++ as_fatal("Couldn't find the .incbin file: \"%s\"", filename); ++ } ++} ++ ++/* ++ * s_data_region() parses and ignores the pseudo op: ++ * .data_region { region_type } ++ * region_type := "jt8" | "jt16" | "jt32" | "jta32" ++ */ ++static ++void ++s_data_region( ++uintptr_t value) ++{ ++ char *region_type, c; ++ ++ c = *input_line_pointer; ++ if(c != '\n'){ ++ region_type = input_line_pointer; ++ do{ ++ c = *input_line_pointer++; ++ }while(c != '\n'); ++ input_line_pointer--; ++ } ++ demand_empty_rest_of_line(); ++} ++ ++/* ++ * s_end_data_region() parses and ignores the pseudo op: ++ * .end_data_region ++ */ ++static ++void ++s_end_data_region( ++uintptr_t value) ++{ ++ demand_empty_rest_of_line(); ++} ++ + #ifdef SPARC + + /* Special stuff to allow assembly of Sun assembler sources +@@ -5061,7 +5018,7 @@ + if (ps_t == 0) + as_bad ("invalid .seg argument"); + +- printf("INDEX %s, %d\n", s, ps_t->poc_val); ++ printf("INDEX %s, %p\n", s, (void *)ps_t->poc_val); + + s_builtin_section ((const struct builtin_section *)ps_t->poc_val); + demand_empty_rest_of_line(); +@@ -5085,8 +5042,164 @@ + static + void + s_ppcasm_end( +-int value) ++uintptr_t value) + { + demand_empty_rest_of_line(); + } + #endif /* PPC */ ++ ++/* Return the size of a LEB128 value. */ ++ ++static inline int ++sizeof_sleb128_32 (int32_t value) ++{ ++ register int size = 0; ++ register unsigned byte; ++ ++ do ++ { ++ byte = (value & 0x7f); ++ /* Sadly, we cannot rely on typical arithmetic right shift behaviour. ++ Fortunately, we can structure things so that the extra work reduces ++ to a noop on systems that do things "properly". */ ++ value = (value >> 7) | ~(-(offsetT)1 >> 7); ++ size += 1; ++ } ++ while (!(((value == 0) && ((byte & 0x40) == 0)) ++ || ((value == -1) && ((byte & 0x40) != 0)))); ++ ++ return size; ++} ++ ++static inline int ++sizeof_sleb128_64 (int64_t value) ++{ ++ register int size = 0; ++ register unsigned byte; ++ ++ do ++ { ++ byte = (value & 0x7f); ++ /* Sadly, we cannot rely on typical arithmetic right shift behaviour. ++ Fortunately, we can structure things so that the extra work reduces ++ to a noop on systems that do things "properly". */ ++ value = (value >> 7) | ~(-(offsetT)1 >> 7); ++ size += 1; ++ } ++ while (!(((value == 0) && ((byte & 0x40) == 0)) ++ || ((value == -1) && ((byte & 0x40) != 0)))); ++ ++ return size; ++} ++ ++static inline int ++sizeof_uleb128_32 (uint32_t value) ++{ ++ register int size = 0; ++ register unsigned byte; ++ ++ do ++ { ++ byte = (value & 0x7f); ++ value >>= 7; ++ size += 1; ++ } ++ while (value != 0); ++ ++ return size; ++} ++ ++static inline int ++sizeof_uleb128_64 (uint64_t value) ++{ ++ register int size = 0; ++ register unsigned byte; ++ ++ do ++ { ++ byte = (value & 0x7f); ++ value >>= 7; ++ size += 1; ++ } ++ while (value != 0); ++ ++ return size; ++} ++ ++#ifdef ARCH64 ++int ++sizeof_leb128 (valueT value, int sign) ++{ ++ if (sign) ++ return sizeof_sleb128_64 ((offsetT) value); ++ else ++ return sizeof_uleb128_64 (value); ++} ++#else ++int ++sizeof_leb128 (valueT value, int sign) ++{ ++ if (sign) ++ return sizeof_sleb128_32 ((offsetT) value); ++ else ++ return sizeof_uleb128_32 (value); ++} ++#endif ++ ++/* Output a LEB128 value. */ ++ ++static inline int ++output_sleb128 (char *p, offsetT value) ++{ ++ register char *orig = p; ++ register int more; ++ ++ do ++ { ++ unsigned byte = (value & 0x7f); ++ ++ /* Sadly, we cannot rely on typical arithmetic right shift behaviour. ++ Fortunately, we can structure things so that the extra work reduces ++ to a noop on systems that do things "properly". */ ++ value = (value >> 7) | ~(-(offsetT)1 >> 7); ++ ++ more = !((((value == 0) && ((byte & 0x40) == 0)) ++ || ((value == -1) && ((byte & 0x40) != 0)))); ++ if (more) ++ byte |= 0x80; ++ ++ *p++ = byte; ++ } ++ while (more); ++ ++ return p - orig; ++} ++ ++static inline int ++output_uleb128 (char *p, valueT value) ++{ ++ char *orig = p; ++ ++ do ++ { ++ unsigned byte = (value & 0x7f); ++ value >>= 7; ++ if (value != 0) ++ /* More bytes to follow. */ ++ byte |= 0x80; ++ ++ *p++ = byte; ++ } ++ while (value != 0); ++ ++ return p - orig; ++} ++ ++int ++output_leb128 (char *p, valueT value, int sign) ++{ ++ if (sign) ++ return output_sleb128 (p, (offsetT) value); ++ else ++ return output_uleb128 (p, value); ++} +Index: odcctools-9.2-ld/as/read.h +=================================================================== +--- odcctools-9.2-ld.orig/as/read.h 2013-09-03 21:08:01.405209526 +0000 ++++ odcctools-9.2-ld/as/read.h 2013-09-03 21:08:01.893209515 +0000 +@@ -29,7 +29,7 @@ + + #ifdef PERMIT_WHITESPACE + #define SKIP_WHITESPACE() \ +- ((*input_line_pointer == ' ') ? ++input_line_pointer : 0) ++ (void)((*input_line_pointer == ' ') ? ++input_line_pointer : 0) + #else + #define SKIP_WHITESPACE() know(*input_line_pointer != ' ' ) + #endif +@@ -46,8 +46,8 @@ + */ + typedef struct { + char *poc_name; /* assembler mnemonic, lower case, no '.' */ +- void (*poc_handler)(int poc_val); /* Do the work */ +- int poc_val; /* Value to pass to handler */ ++ void (*poc_handler)(uintptr_t poc_val); /* Do the work */ ++ uintptr_t poc_val; /* Value to pass to handler */ + } pseudo_typeS; + + extern char *input_line_pointer; /* -> char we are parsing now. */ +@@ -63,7 +63,16 @@ + char lex_type[]; + extern char is_end_of_line( + int c); +-extern unsigned long text_nsect; ++extern uint32_t text_nsect; ++ ++/* ++ * These variable are set with .inlineasmstart and used when reporting errors ++ * for the properties of GCC function-scope inline asms. ++ */ ++extern int inlineasm_checks; ++extern char *inlineasm_file_name; ++extern int inlineasm_line_number; ++extern int inlineasm_column_number; + + extern void read_begin( + void); +@@ -75,6 +84,8 @@ + char *buffer); + extern signed_target_addr_t get_absolute_expression( + void); ++extern char *demand_copy_C_string( ++ int *len_pointer); + extern void demand_empty_rest_of_line( + void); + extern void ignore_rest_of_line( +@@ -88,35 +99,36 @@ + + /* globally known pseudo-op functions (used by some assemblers in MACHINE.c) */ + extern void stringer( +- int append_zero); ++ uintptr_t append_zero); + extern void s_space( +- int value); ++ uintptr_t value); + extern void s_abs( +- int value); ++ uintptr_t value); + extern void float_cons( +- int float_type); ++ uintptr_t float_type); + extern void cons( +- int nbytes); ++ uintptr_t nbytes); + extern void s_globl( +- int value); ++ uintptr_t value); ++void s_app_file( ++ uintptr_t value); + extern void s_ignore( +- int arg); ++ uintptr_t arg); + extern void s_line( +- int value); ++ uintptr_t value); + extern void s_macro( +- int value); ++ uintptr_t value); + extern void s_endmacro( +- int value); +-extern void s_rept( +- int value); +-extern void s_endr( +- int value); +-extern void s_ifnc( +- int value); +-extern void s_ifc( +- int value); +-extern void s_ifdef( +- int value); ++ uintptr_t value); + extern void big_cons( +- int nbytes); ++ uintptr_t nbytes); ++extern void pseudo_set( ++ symbolS *symbolP); ++extern int output_leb128( ++ char *p, ++ valueT value, ++ int sign); ++extern int sizeof_leb128( ++ valueT value, ++ int sign); + #endif /* _READ_H_ */ +Index: odcctools-9.2-ld/as/relax.h +=================================================================== +--- odcctools-9.2-ld.orig/as/relax.h 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/as/relax.h 2013-09-03 21:08:01.893209515 +0000 +@@ -1,5 +1,9 @@ + /* The type used for a target address */ +-typedef unsigned long relax_addressT; ++#ifdef ARCH64 ++typedef uint64_t relax_addressT; ++#else ++typedef uint32_t relax_addressT; ++#endif + + /* + * relax_stateT is a fragment's type and stored in a struct frag's fr_type +@@ -15,6 +19,8 @@ + rs_org, /* Org: Fr_offset, fr_symbol: address. */ + /* 1 variable char: fill character. */ + rs_machine_dependent, ++ rs_dwarf2dbg, ++ rs_leb128 /* leb128 value, subtype is 0 for 1 for signed. */ + } relax_stateT; + + /* +@@ -25,7 +31,7 @@ + * The substate is a machine dependent indication of what type of branch + * instruction this fragment is. + */ +-typedef unsigned long relax_substateT; ++typedef uint32_t relax_substateT; + + /* + * relax_typeS is the structure that is the entry in the md_relax_table array. +Index: odcctools-9.2-ld/as/sections.h +=================================================================== +--- odcctools-9.2-ld.orig/as/sections.h 2013-09-03 21:08:01.409209526 +0000 ++++ odcctools-9.2-ld/as/sections.h 2013-09-03 21:08:01.893209515 +0000 +@@ -17,6 +17,7 @@ + along with GAS; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + ++#include <stdint.h> + #include <mach-o/loader.h> + #include "struc-symbol.h" + +@@ -37,10 +38,13 @@ + struct frchain *frch_next; /* next in chain of struct frchain-s */ + + section_t frch_section; /* section info, name, type, etc. */ +- unsigned long frch_nsect; /* section number (1,2,3,...) */ ++ uint32_t frch_nsect; /* section number (1,2,3,...) */ + struct fix *frch_fix_root; /* section fixups */ + isymbolS *frch_isym_root; /* 1st indirect symbol in chain */ + isymbolS *frch_isym_last; /* last indirect symbol in chain */ ++ symbolS *section_symbol; /* section symbol for dwarf if set */ ++ uint32_t has_rs_leb128s; /* section has some rs_leb128 frags */ ++ uint32_t layout_pass; /* pass order for layout_addresses() */ + }; + + typedef struct frchain frchainS; +@@ -57,6 +61,14 @@ + extern frchainS *frchain_now; + + /* ++ * These are used to inteface to the code in dwarf2dbg.c . The first is the ++ * frch_nsect value from the current frchain or current section. The second ++ * is always zero. ++ */ ++extern int now_seg; ++extern int now_subseg; ++ ++/* + * The global routines defined in sections.c + */ + extern void sections_begin( +@@ -65,25 +77,41 @@ + extern frchainS *section_new( + char *segname, + char *sectname, +- unsigned long type, +- unsigned long attributes, +- unsigned long sizeof_stub); ++ uint32_t type, ++ uint32_t attributes, ++ uint32_t sizeof_stub); ++ ++extern void section_set( ++ frchainS *frcP); ++ ++extern symbolS *section_symbol( ++ frchainS *frcP); ++ ++extern int seg_not_empty_p( ++ frchainS *frcP); ++ ++extern struct frchain *get_section_by_nsect( ++ uint32_t nsect); ++ ++extern struct frchain *get_section_by_name( ++ char *segname, ++ char *sectname); + +-extern unsigned long is_section_coalesced( +- unsigned long n_sect); ++extern uint32_t is_section_coalesced( ++ uint32_t n_sect); + +-extern unsigned long is_section_non_lazy_symbol_pointers( +- unsigned long n_sect); ++extern uint32_t is_section_non_lazy_symbol_pointers( ++ uint32_t n_sect); + +-extern unsigned long is_section_debug( +- unsigned long n_sect); ++extern uint32_t is_section_debug( ++ uint32_t n_sect); + +-extern unsigned long is_section_cstring_literals( +- unsigned long n_sect); ++extern uint32_t is_section_cstring_literals( ++ uint32_t n_sect); + +-extern unsigned long is_end_section_address( +- unsigned long n_sect, +- unsigned long addr); ++extern uint32_t is_end_section_address( ++ uint32_t n_sect, ++ addressT addr); + +-extern unsigned long section_has_fixed_size_data( +- unsigned long n_sect); ++extern uint32_t section_has_fixed_size_data( ++ uint32_t n_sect); +Index: odcctools-9.2-ld/include/mach-o/loader.h +=================================================================== +--- odcctools-9.2-ld.orig/include/mach-o/loader.h 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/include/mach-o/loader.h 2013-09-03 21:08:01.893209515 +0000 +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 1999-2008 Apple Inc. All Rights Reserved. ++ * Copyright (c) 1999-2010 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * +@@ -119,6 +119,7 @@ + /* linking only, no section contents */ + #define MH_DSYM 0xa /* companion file with only debug */ + /* sections */ ++#define MH_KEXT_BUNDLE 0xb /* x86_64 kexts */ + + /* Constants for the flags field of the mach_header */ + #define MH_NOUNDEFS 0x1 /* the object file has no undefined +@@ -189,6 +190,22 @@ + load the main executable at a + random address. Only used in + MH_EXECUTE filetypes. */ ++#define MH_DEAD_STRIPPABLE_DYLIB 0x400000 /* Only for use on dylibs. When ++ linking against a dylib that ++ has this bit set, the static linker ++ will automatically not create a ++ LC_LOAD_DYLIB load command to the ++ dylib if no symbols are being ++ referenced from the dylib. */ ++#define MH_HAS_TLV_DESCRIPTORS 0x800000 /* Contains a section of type ++ S_THREAD_LOCAL_VARIABLES */ ++ ++#define MH_NO_HEAP_EXECUTION 0x1000000 /* When this bit is set, the OS will ++ run the main executable with ++ a non-executable heap even on ++ platforms (e.g. i386) that don't ++ require it. Only used in MH_EXECUTE ++ filetypes. */ + + /* + * The load commands directly follow the mach_header. The total size of all +@@ -248,7 +265,6 @@ + #define LC_SUB_LIBRARY 0x15 /* sub library */ + #define LC_TWOLEVEL_HINTS 0x16 /* two-level namespace lookup hints */ + #define LC_PREBIND_CKSUM 0x17 /* prebind checksum */ +-#define LC_ENCRYPTION_INFO 0x21 /* encrypted segment information */ + + /* + * load a dynamically linked shared library that is allowed to be missing +@@ -264,6 +280,22 @@ + #define LC_CODE_SIGNATURE 0x1d /* local of code signature */ + #define LC_SEGMENT_SPLIT_INFO 0x1e /* local of info to split segments */ + #define LC_REEXPORT_DYLIB (0x1f | LC_REQ_DYLD) /* load and re-export dylib */ ++#define LC_LAZY_LOAD_DYLIB 0x20 /* delay load of dylib until first use */ ++#define LC_ENCRYPTION_INFO 0x21 /* encrypted segment information */ ++#define LC_DYLD_INFO 0x22 /* compressed dyld information */ ++#define LC_DYLD_INFO_ONLY (0x22|LC_REQ_DYLD) /* compressed dyld information only */ ++#define LC_LOAD_UPWARD_DYLIB (0x23 | LC_REQ_DYLD) /* load upward dylib */ ++#define LC_VERSION_MIN_MACOSX 0x24 /* build for MacOSX min OS version */ ++#define LC_VERSION_MIN_IPHONEOS 0x25 /* build for iPhoneOS min OS version */ ++#define LC_FUNCTION_STARTS 0x26 /* compressed table of function start addresses */ ++#define LC_DYLD_ENVIRONMENT 0x27 /* string for dyld to treat ++ like environment variable */ ++#define LC_MAIN (0x28|LC_REQ_DYLD) /* replacement for LC_UNIXTHREAD */ ++#define LC_DATA_IN_CODE 0x29 /* table of non-instructions in __text */ ++#define LC_SOURCE_VERSION 0x2A /* source version used to build binary */ ++#define LC_DYLIB_CODE_SIGN_DRS 0x2B /* Code signing DRs copied from linked dylibs */ ++#define LC_ENCRYPTION_INFO_64 0x2C /* 64-bit encrypted segment information */ ++ + + /* + * A variable length string in a load command is represented by an lc_str +@@ -450,6 +482,23 @@ + literals */ + #define S_DTRACE_DOF 0xf /* section contains + DTrace Object Format */ ++#define S_LAZY_DYLIB_SYMBOL_POINTERS 0x10 /* section with only lazy ++ symbol pointers to lazy ++ loaded dylibs */ ++/* ++ * Section types to support thread local variables ++ */ ++#define S_THREAD_LOCAL_REGULAR 0x11 /* template of initial ++ values for TLVs */ ++#define S_THREAD_LOCAL_ZEROFILL 0x12 /* template of initial ++ values for TLVs */ ++#define S_THREAD_LOCAL_VARIABLES 0x13 /* TLV descriptors */ ++#define S_THREAD_LOCAL_VARIABLE_POINTERS 0x14 /* pointers to TLV ++ descriptors */ ++#define S_THREAD_LOCAL_INIT_FUNCTION_POINTERS 0x15 /* functions to call ++ to initialize TLV ++ values */ ++ + /* + * Constants for the section attributes part of the flags field of a section + * structure. +@@ -696,9 +745,12 @@ + * the name of the dynamic linker (LC_LOAD_DYLINKER). And a dynamic linker + * contains a dylinker_command to identify the dynamic linker (LC_ID_DYLINKER). + * A file can have at most one of these. ++ * This struct is also used for the LC_DYLD_ENVIRONMENT load command and ++ * contains string for dyld to treat like environment variable. + */ + struct dylinker_command { +- uint32_t cmd; /* LC_ID_DYLINKER or LC_LOAD_DYLINKER */ ++ uint32_t cmd; /* LC_ID_DYLINKER, LC_LOAD_DYLINKER or ++ LC_DYLD_ENVIRONMENT */ + uint32_t cmdsize; /* includes pathname string */ + union lc_str name; /* dynamic linker's path name */ + }; +@@ -1102,26 +1154,226 @@ + * of data in the __LINKEDIT segment. + */ + struct linkedit_data_command { +- uint32_t cmd; /* LC_CODE_SIGNATURE or LC_SEGMENT_SPLIT_INFO */ ++ uint32_t cmd; /* LC_CODE_SIGNATURE, LC_SEGMENT_SPLIT_INFO, ++ LC_FUNCTION_STARTS, LC_DATA_IN_CODE, ++ or LC_DYLIB_CODE_SIGN_DRS */ + uint32_t cmdsize; /* sizeof(struct linkedit_data_command) */ + uint32_t dataoff; /* file offset of data in __LINKEDIT segment */ + uint32_t datasize; /* file size of data in __LINKEDIT segment */ + }; + +- + /* + * The encryption_info_command contains the file offset and size of an +- * of an encrypted segment. ++ * of an encrypted segment. + */ + struct encryption_info_command { +- uint32_t cmd; /* LC_ENCRYPTION_INFO */ +- uint32_t cmdsize; /* sizeof(struct encryption_info_command) */ +- uint32_t cryptoff; /* file offset of encrypted range */ +- uint32_t cryptsize; /* file size of encrypted range */ +- uint32_t cryptid; /* which enryption system, +- 0 means not-encrypted yet */ ++ uint32_t cmd; /* LC_ENCRYPTION_INFO */ ++ uint32_t cmdsize; /* sizeof(struct encryption_info_command) */ ++ uint32_t cryptoff; /* file offset of encrypted range */ ++ uint32_t cryptsize; /* file size of encrypted range */ ++ uint32_t cryptid; /* which enryption system, ++ 0 means not-encrypted yet */ ++}; ++ ++/* ++ * The encryption_info_command_64 contains the file offset and size of an ++ * of an encrypted segment (for use in 64-bit targets). ++ */ ++struct encryption_info_command_64 { ++ uint32_t cmd; /* LC_ENCRYPTION_INFO_64 */ ++ uint32_t cmdsize; /* sizeof(struct encryption_info_command_64) */ ++ uint32_t cryptoff; /* file offset of encrypted range */ ++ uint32_t cryptsize; /* file size of encrypted range */ ++ uint32_t cryptid; /* which enryption system, ++ 0 means not-encrypted yet */ ++ uint32_t pad; /* padding to make this struct's size a multiple ++ of 8 bytes */ + }; + ++/* ++ * The version_min_command contains the min OS version on which this ++ * binary was built to run. ++ */ ++struct version_min_command { ++ uint32_t cmd; /* LC_VERSION_MIN_MACOSX or ++ LC_VERSION_MIN_IPHONEOS */ ++ uint32_t cmdsize; /* sizeof(struct min_version_command) */ ++ uint32_t version; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */ ++ uint32_t sdk; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */ ++}; ++ ++/* ++ * The dyld_info_command contains the file offsets and sizes of ++ * the new compressed form of the information dyld needs to ++ * load the image. This information is used by dyld on Mac OS X ++ * 10.6 and later. All information pointed to by this command ++ * is encoded using byte streams, so no endian swapping is needed ++ * to interpret it. ++ */ ++struct dyld_info_command { ++ uint32_t cmd; /* LC_DYLD_INFO or LC_DYLD_INFO_ONLY */ ++ uint32_t cmdsize; /* sizeof(struct dyld_info_command) */ ++ ++ /* ++ * Dyld rebases an image whenever dyld loads it at an address different ++ * from its preferred address. The rebase information is a stream ++ * of byte sized opcodes whose symbolic names start with REBASE_OPCODE_. ++ * Conceptually the rebase information is a table of tuples: ++ * <seg-index, seg-offset, type> ++ * The opcodes are a compressed way to encode the table by only ++ * encoding when a column changes. In addition simple patterns ++ * like "every n'th offset for m times" can be encoded in a few ++ * bytes. ++ */ ++ uint32_t rebase_off; /* file offset to rebase info */ ++ uint32_t rebase_size; /* size of rebase info */ ++ ++ /* ++ * Dyld binds an image during the loading process, if the image ++ * requires any pointers to be initialized to symbols in other images. ++ * The bind information is a stream of byte sized ++ * opcodes whose symbolic names start with BIND_OPCODE_. ++ * Conceptually the bind information is a table of tuples: ++ * <seg-index, seg-offset, type, symbol-library-ordinal, symbol-name, addend> ++ * The opcodes are a compressed way to encode the table by only ++ * encoding when a column changes. In addition simple patterns ++ * like for runs of pointers initialzed to the same value can be ++ * encoded in a few bytes. ++ */ ++ uint32_t bind_off; /* file offset to binding info */ ++ uint32_t bind_size; /* size of binding info */ ++ ++ /* ++ * Some C++ programs require dyld to unique symbols so that all ++ * images in the process use the same copy of some code/data. ++ * This step is done after binding. The content of the weak_bind ++ * info is an opcode stream like the bind_info. But it is sorted ++ * alphabetically by symbol name. This enable dyld to walk ++ * all images with weak binding information in order and look ++ * for collisions. If there are no collisions, dyld does ++ * no updating. That means that some fixups are also encoded ++ * in the bind_info. For instance, all calls to "operator new" ++ * are first bound to libstdc++.dylib using the information ++ * in bind_info. Then if some image overrides operator new ++ * that is detected when the weak_bind information is processed ++ * and the call to operator new is then rebound. ++ */ ++ uint32_t weak_bind_off; /* file offset to weak binding info */ ++ uint32_t weak_bind_size; /* size of weak binding info */ ++ ++ /* ++ * Some uses of external symbols do not need to be bound immediately. ++ * Instead they can be lazily bound on first use. The lazy_bind ++ * are contains a stream of BIND opcodes to bind all lazy symbols. ++ * Normal use is that dyld ignores the lazy_bind section when ++ * loading an image. Instead the static linker arranged for the ++ * lazy pointer to initially point to a helper function which ++ * pushes the offset into the lazy_bind area for the symbol ++ * needing to be bound, then jumps to dyld which simply adds ++ * the offset to lazy_bind_off to get the information on what ++ * to bind. ++ */ ++ uint32_t lazy_bind_off; /* file offset to lazy binding info */ ++ uint32_t lazy_bind_size; /* size of lazy binding infs */ ++ ++ /* ++ * The symbols exported by a dylib are encoded in a trie. This ++ * is a compact representation that factors out common prefixes. ++ * It also reduces LINKEDIT pages in RAM because it encodes all ++ * information (name, address, flags) in one small, contiguous range. ++ * The export area is a stream of nodes. The first node sequentially ++ * is the start node for the trie. ++ * ++ * Nodes for a symbol start with a uleb128 that is the length of ++ * the exported symbol information for the string so far. ++ * If there is no exported symbol, the node starts with a zero byte. ++ * If there is exported info, it follows the length. ++ * ++ * First is a uleb128 containing flags. Normally, it is followed by ++ * a uleb128 encoded offset which is location of the content named ++ * by the symbol from the mach_header for the image. If the flags ++ * is EXPORT_SYMBOL_FLAGS_REEXPORT, then following the flags is ++ * a uleb128 encoded library ordinal, then a zero terminated ++ * UTF8 string. If the string is zero length, then the symbol ++ * is re-export from the specified dylib with the same name. ++ * If the flags is EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER, then following ++ * the flags is two uleb128s: the stub offset and the resolver offset. ++ * The stub is used by non-lazy pointers. The resolver is used ++ * by lazy pointers and must be called to get the actual address to use. ++ * ++ * After the optional exported symbol information is a byte of ++ * how many edges (0-255) that this node has leaving it, ++ * followed by each edge. ++ * Each edge is a zero terminated UTF8 of the addition chars ++ * in the symbol, followed by a uleb128 offset for the node that ++ * edge points to. ++ * ++ */ ++ uint32_t export_off; /* file offset to lazy binding info */ ++ uint32_t export_size; /* size of lazy binding infs */ ++}; ++ ++/* ++ * The following are used to encode rebasing information ++ */ ++#define REBASE_TYPE_POINTER 1 ++#define REBASE_TYPE_TEXT_ABSOLUTE32 2 ++#define REBASE_TYPE_TEXT_PCREL32 3 ++ ++#define REBASE_OPCODE_MASK 0xF0 ++#define REBASE_IMMEDIATE_MASK 0x0F ++#define REBASE_OPCODE_DONE 0x00 ++#define REBASE_OPCODE_SET_TYPE_IMM 0x10 ++#define REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB 0x20 ++#define REBASE_OPCODE_ADD_ADDR_ULEB 0x30 ++#define REBASE_OPCODE_ADD_ADDR_IMM_SCALED 0x40 ++#define REBASE_OPCODE_DO_REBASE_IMM_TIMES 0x50 ++#define REBASE_OPCODE_DO_REBASE_ULEB_TIMES 0x60 ++#define REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB 0x70 ++#define REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB 0x80 ++ ++ ++/* ++ * The following are used to encode binding information ++ */ ++#define BIND_TYPE_POINTER 1 ++#define BIND_TYPE_TEXT_ABSOLUTE32 2 ++#define BIND_TYPE_TEXT_PCREL32 3 ++ ++#define BIND_SPECIAL_DYLIB_SELF 0 ++#define BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE -1 ++#define BIND_SPECIAL_DYLIB_FLAT_LOOKUP -2 ++ ++#define BIND_SYMBOL_FLAGS_WEAK_IMPORT 0x1 ++#define BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION 0x8 ++ ++#define BIND_OPCODE_MASK 0xF0 ++#define BIND_IMMEDIATE_MASK 0x0F ++#define BIND_OPCODE_DONE 0x00 ++#define BIND_OPCODE_SET_DYLIB_ORDINAL_IMM 0x10 ++#define BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB 0x20 ++#define BIND_OPCODE_SET_DYLIB_SPECIAL_IMM 0x30 ++#define BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM 0x40 ++#define BIND_OPCODE_SET_TYPE_IMM 0x50 ++#define BIND_OPCODE_SET_ADDEND_SLEB 0x60 ++#define BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB 0x70 ++#define BIND_OPCODE_ADD_ADDR_ULEB 0x80 ++#define BIND_OPCODE_DO_BIND 0x90 ++#define BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB 0xA0 ++#define BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED 0xB0 ++#define BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB 0xC0 ++ ++ ++/* ++ * The following are used on the flags byte of a terminal node ++ * in the export information. ++ */ ++#define EXPORT_SYMBOL_FLAGS_KIND_MASK 0x03 ++#define EXPORT_SYMBOL_FLAGS_KIND_REGULAR 0x00 ++#define EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL 0x01 ++#define EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION 0x04 ++#define EXPORT_SYMBOL_FLAGS_REEXPORT 0x08 ++#define EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER 0x10 + + /* + * The symseg_command contains the offset and size of the GNU style +@@ -1163,4 +1415,59 @@ + uint32_t header_addr; /* files virtual address */ + }; + ++ ++/* ++ * The entry_point_command is a replacement for thread_command. ++ * It is used for main executables to specify the location (file offset) ++ * of main(). If -stack_size was used at link time, the stacksize ++ * field will contain the stack size need for the main thread. ++ */ ++struct entry_point_command { ++ uint32_t cmd; /* LC_MAIN only used in MH_EXECUTE filetypes */ ++ uint32_t cmdsize; /* 24 */ ++ uint64_t entryoff; /* file (__TEXT) offset of main() */ ++ uint64_t stacksize;/* if not zero, initial stack size */ ++}; ++ ++ ++/* ++ * The source_version_command is an optional load command containing ++ * the version of the sources used to build the binary. ++ */ ++struct source_version_command { ++ uint32_t cmd; /* LC_SOURCE_VERSION */ ++ uint32_t cmdsize; /* 16 */ ++ uint64_t version; /* A.B.C.D.E packed as a24.b10.c10.d10.e10 */ ++}; ++ ++ ++/* ++ * The LC_DATA_IN_CODE load commands uses a linkedit_data_command ++ * to point to an array of data_in_code_entry entries. Each entry ++ * describes a range of data in a code section. ++ */ ++struct data_in_code_entry { ++ uint32_t offset; /* from mach_header to start of data range*/ ++ uint16_t length; /* number of bytes in data range */ ++ uint16_t kind; /* a DICE_KIND_* value */ ++}; ++#define DICE_KIND_DATA 0x0001 ++#define DICE_KIND_JUMP_TABLE8 0x0002 ++#define DICE_KIND_JUMP_TABLE16 0x0003 ++#define DICE_KIND_JUMP_TABLE32 0x0004 ++#define DICE_KIND_ABS_JUMP_TABLE32 0x0005 ++ ++ ++ ++/* ++ * Sections of type S_THREAD_LOCAL_VARIABLES contain an array ++ * of tlv_descriptor structures. ++ */ ++struct tlv_descriptor ++{ ++ void* (*thunk)(struct tlv_descriptor*); ++ unsigned long key; ++ unsigned long offset; ++}; ++ + #endif /* _MACHO_LOADER_H_ */ +Index: odcctools-9.2-ld/include/mach-o/nlist.h +=================================================================== +--- odcctools-9.2-ld.orig/include/mach-o/nlist.h 2013-09-03 21:08:01.481209525 +0000 ++++ odcctools-9.2-ld/include/mach-o/nlist.h 2013-09-03 21:08:01.893209515 +0000 +@@ -76,7 +76,7 @@ + struct nlist { + union { + char *n_name; /* for use when in-core */ +- int32_t n_strx; /* index into the string table */ ++ uint32_t n_strx; /* index into the string table */ + } n_un; + uint8_t n_type; /* type flag, see below */ + uint8_t n_sect; /* section number or NO_SECT */ +@@ -284,11 +284,25 @@ + */ + #define N_ARM_THUMB_DEF 0x0008 /* symbol is a Thumb function (ARM) */ + ++/* ++ * The N_SYMBOL_RESOLVER bit of the n_desc field indicates that the ++ * that the function is actually a resolver function and should ++ * be called to get the address of the real function to use. ++ * This bit is only available in .o files (MH_OBJECT filetype) ++ */ ++#define N_SYMBOL_RESOLVER 0x0100 ++ + #ifndef __STRICT_BSD__ ++#if __cplusplus ++extern "C" { ++#endif /* __cplusplus */ + /* + * The function nlist(3) from the C library. + */ + extern int nlist (const char *filename, struct nlist *list); ++#if __cplusplus ++} ++#endif /* __cplusplus */ + #endif /* __STRICT_BSD__ */ + + #endif /* _MACHO_LIST_H_ */ +Index: odcctools-9.2-ld/as/arm.c +=================================================================== +--- odcctools-9.2-ld.orig/as/arm.c 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/as/arm.c 2013-09-03 21:08:01.897209515 +0000 +@@ -113,7 +113,7 @@ + /* STUFF FROM gas/as.h */ + #define COMMON + COMMON subsegT now_subseg; +-COMMON segT now_seg; ++/*COMMON segT now_seg;*/ + + /* STUFF FROM gas/config/tc-arm.h */ + /* FROM line 109 */ +@@ -139,6 +139,7 @@ + #define ISALPHA(c) isalpha(c) + #define ISDIGIT(c) isdigit(c) + #define TOUPPER(c) toupper(c) ++#define TOLOWER(c) tolower(c) + + /* FROM line 137 */ + #define streq(a, b) (strcmp (a, b) == 0) +@@ -9807,7 +9808,7 @@ + /* The knowledge of the PC's pipeline offset is built into the insns + themselves. */ + +-long ++int32_t + md_pcrel_from (const fixS * fixP) + { + #ifdef NOTYET +Index: odcctools-9.2-ld/as/filenames.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ odcctools-9.2-ld/as/filenames.h 2013-09-03 21:08:01.897209515 +0000 +@@ -0,0 +1,52 @@ ++/* Macros for taking apart, interpreting and processing file names. ++ ++ These are here because some non-Posix (a.k.a. DOSish) systems have ++ drive letter brain-damage at the beginning of an absolute file name, ++ use forward- and back-slash in path names interchangeably, and ++ some of them have case-insensitive file names. ++ ++ Copyright 2000, 2001, 2007 Free Software Foundation, Inc. ++ ++This file is part of BFD, the Binary File Descriptor library. ++ ++This program is free software; you can redistribute it and/or modify ++it under the terms of the GNU General Public License as published by ++the Free Software Foundation; either version 2 of the License, or ++(at your option) any later version. ++ ++This program is distributed in the hope that it will be useful, ++but WITHOUT ANY WARRANTY; without even the implied warranty of ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++GNU General Public License for more details. ++ ++You should have received a copy of the GNU General Public License ++along with this program; if not, write to the Free Software ++Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ ++ ++#ifndef FILENAMES_H ++#define FILENAMES_H ++ ++#if defined(__MSDOS__) || defined(_WIN32) || defined(__OS2__) || defined (__CYGWIN__) ++ ++#ifndef HAVE_DOS_BASED_FILE_SYSTEM ++#define HAVE_DOS_BASED_FILE_SYSTEM 1 ++#endif ++ ++#define IS_DIR_SEPARATOR(c) ((c) == '/' || (c) == '\\') ++/* Note that IS_ABSOLUTE_PATH accepts d:foo as well, although it is ++ only semi-absolute. This is because the users of IS_ABSOLUTE_PATH ++ want to know whether to prepend the current working directory to ++ a file name, which should not be done with a name like d:foo. */ ++#define IS_ABSOLUTE_PATH(f) (IS_DIR_SEPARATOR((f)[0]) || (((f)[0]) && ((f)[1] == ':'))) ++ ++#else /* not DOSish */ ++ ++#define IS_DIR_SEPARATOR(c) ((c) == '/') ++#define IS_ABSOLUTE_PATH(f) (IS_DIR_SEPARATOR((f)[0])) ++ ++#endif /* not DOSish */ ++ ++extern int filename_cmp (const char *s1, const char *s2); ++#define FILENAME_CMP(s1, s2) filename_cmp(s1, s2) ++ ++#endif /* FILENAMES_H */ +Index: odcctools-9.2-ld/as/sections.c +=================================================================== +--- odcctools-9.2-ld.orig/as/sections.c 2013-09-03 21:08:01.409209526 +0000 ++++ odcctools-9.2-ld/as/sections.c 2013-09-03 21:08:01.897209515 +0000 +@@ -32,6 +32,7 @@ + #include "xmalloc.h" + #include "frags.h" + #include "messages.h" ++#include "symbols.h" + + /* + * All sections' chains hang off here. NULL means no frchains yet. +@@ -45,6 +46,21 @@ + frchainS *frchain_now = NULL; + + /* ++ * The variables now_seg and now_subseg are defined here and used slightly ++ * differently than in GAS so it works with Mach-O files and the code generating ++ * dwarf debug info. ++ * ++ * The variable now_seg contains the current section number that is what is ++ * stored in the struct frchain's field frch_nsect. And is set by section_new() ++ * in here and also used in layout.c. The variable now_subseg always remains ++ * zero. And is defined to minimize changes to dwarf2dbg.c that uses it. ++ * Note, now_seg is never set to a section number of a section with a type of ++ * S_ZEROFILL or S_THREAD_LOCAL_ZEROFILL. ++ */ ++int now_seg = 0; ++int now_subseg = 0; ++ ++/* + * sections_begin() sets up to allow sections to be created. + */ + void +@@ -77,18 +93,20 @@ + * frchain_now points to the (possibly new) struct frchain for this section. + * frchain_root updated if needed (for the first section created). + * frag_now is set to the last (possibly new) frag in the section. ++ * now_seg is set to the Mach-O section number (frch_nsect field) except ++ * it is not set for section types of S_ZEROFILL or S_THREAD_LOCAL_ZEROFILL. + */ + frchainS * + section_new( + char *segname, + char *sectname, +-unsigned long type, +-unsigned long attributes, +-unsigned long sizeof_stub) ++uint32_t type, ++uint32_t attributes, ++uint32_t sizeof_stub) + { + frchainS *frcP; + frchainS **lastPP; +- unsigned long last_nsect; ++ uint32_t last_nsect; + + if(frags.chunk_size == 0) + /* +@@ -142,7 +160,10 @@ + * If the current section is the same as for this call there is nothing + * more to do. + */ +- if(frcP != NULL && (frchain_now == frcP || type == S_ZEROFILL)){ ++ if(frcP != NULL && (frchain_now == frcP || type == S_ZEROFILL || ++ type == S_THREAD_LOCAL_ZEROFILL)){ ++ if(type != S_ZEROFILL && type != S_THREAD_LOCAL_ZEROFILL) ++ now_seg = frcP->frch_nsect; + return(frcP); + } + +@@ -150,7 +171,7 @@ + * For non-zerofill sections it will be made the current section so deal + * with the current frag. + */ +- if(type != S_ZEROFILL){ ++ if(type != S_ZEROFILL && type != S_THREAD_LOCAL_ZEROFILL){ + /* + * If there is any current frag in the old section close it off. + */ +@@ -167,7 +188,7 @@ + * on a address that is aligned correctly for the engine that runs + * the assembler. + */ +- obstack_finish(&frags); ++ (void)obstack_finish(&frags); + } + + /* +@@ -175,11 +196,15 @@ + * it by making it the current chain and create a new frag in it. + */ + if(frcP != NULL){ ++ if(type != S_ZEROFILL && type != S_THREAD_LOCAL_ZEROFILL) ++ now_seg = frcP->frch_nsect; + /* + * For a zerofill section no frags are created here and since it +- * exist just return a pointer to the section. ++ * exists just return a pointer to the section. + */ +- if((frcP->frch_section.flags & SECTION_TYPE) == S_ZEROFILL){ ++ if((frcP->frch_section.flags & SECTION_TYPE) == S_ZEROFILL || ++ (frcP->frch_section.flags & SECTION_TYPE) == ++ S_THREAD_LOCAL_ZEROFILL){ + return(frcP); + } + else{ +@@ -187,6 +212,8 @@ + * Make this section the current section. + */ + frchain_now = frcP; ++ if(type != S_ZEROFILL && type != S_THREAD_LOCAL_ZEROFILL) ++ now_seg = frchain_now->frch_nsect; + + /* + * Make a fresh frag for the section. +@@ -216,7 +243,11 @@ + frcP->frch_section.flags = attributes | type; + frcP->frch_section.reserved2 = sizeof_stub; + ++ if(last_nsect + 1 > MAX_SECT) ++ as_fatal("too many sections (maximum %d)\n", MAX_SECT); + frcP->frch_nsect = last_nsect + 1; ++ if(type != S_ZEROFILL && type != S_THREAD_LOCAL_ZEROFILL) ++ now_seg = frcP->frch_nsect; + + *lastPP = frcP; + +@@ -225,7 +256,7 @@ + * For non-zerofill section create the sections new frag and + * make the section the current chain. + */ +- if(type == S_ZEROFILL){ ++ if(type == S_ZEROFILL || type == S_THREAD_LOCAL_ZEROFILL){ + return(frcP); + } + else{ +@@ -251,9 +282,91 @@ + return(frchain_now); + } + +-unsigned long ++/* ++ * section_set() sets the current section to passed section pointer struct. ++ * This is used by dwarf2dbg.c before emiting the debug sections. ++ */ ++void ++section_set( ++frchainS *frcP) ++{ ++ section_new(frcP->frch_section.segname, frcP->frch_section.sectname, ++ frcP->frch_section.flags & SECTION_TYPE, ++ frcP->frch_section.flags & SECTION_ATTRIBUTES, ++ frcP->frch_section.reserved2); ++} ++ ++/* ++ * section_symbol() creates and stores (if needed) a symbol for the start of ++ * the section. This is used by code in dwarf2dbg.c . ++ */ ++symbolS * ++section_symbol( ++frchainS *frcP) ++{ ++ if(frcP->section_symbol == NULL){ ++ frcP->section_symbol = symbol_temp_new(frcP->frch_nsect, ++ 0, ++ frcP->frch_root); ++ } ++ return(frcP->section_symbol); ++} ++ ++/* Return non zero if the section has at least one byte of data. It is ++ possible that we'll return zero even on a non-empty section because ++ we don't know all the fragment types, and it is possible that an ++ fr_fix == 0 one still contributes data. Think of this as ++ seg_definitely_not_empty_p. */ ++int ++seg_not_empty_p( ++frchainS *frcP) ++{ ++ fragS *frag; ++ ++ if(frcP == NULL) ++ return(0); ++ ++ for(frag = frcP->frch_root; frag; frag = frag->fr_next){ ++ if(frag->fr_fix != 0) ++ return 1; ++ } ++ return 0; ++} ++ ++ ++struct frchain * ++get_section_by_nsect( ++uint32_t nsect) ++{ ++ struct frchain *frchainP; ++ ++ for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){ ++ if(frchainP->frch_nsect == nsect) ++ return(frchainP); ++ } ++ return(NULL); ++} ++ ++struct frchain * ++get_section_by_name( ++char *segname, ++char *sectname) ++{ ++ struct frchain *frchainP; ++ ++ for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){ ++ if(strncmp(frchainP->frch_section.segname, segname, ++ sizeof(frchainP->frch_section.segname)) == 0 && ++ strncmp(frchainP->frch_section.sectname, sectname, ++ sizeof(frchainP->frch_section.sectname)) == 0) ++ return(frchainP); ++ } ++ return(NULL); ++} ++ ++uint32_t + is_section_coalesced( +-unsigned long n_sect) ++uint32_t n_sect) + { + struct frchain *frchainP; + +@@ -265,9 +378,9 @@ + return(0); /* FALSE */ + } + +-unsigned long ++uint32_t + is_section_non_lazy_symbol_pointers( +-unsigned long n_sect) ++uint32_t n_sect) + { + struct frchain *frchainP; + +@@ -280,9 +393,9 @@ + return(0); /* FALSE */ + } + +-unsigned long ++uint32_t + is_section_debug( +-unsigned long n_sect) ++uint32_t n_sect) + { + struct frchain *frchainP; + +@@ -295,9 +408,9 @@ + return(0); /* FALSE */ + } + +-unsigned long ++uint32_t + is_section_cstring_literals( +-unsigned long n_sect) ++uint32_t n_sect) + { + struct frchain *frchainP; + +@@ -310,16 +423,19 @@ + return(0); /* FALSE */ + } + +-unsigned long ++uint32_t + is_end_section_address( +-unsigned long n_sect, +-unsigned long addr) ++uint32_t n_sect, ++addressT addr) + { + struct frchain *frchainP; ++ uint32_t section_type; + + for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){ + if(frchainP->frch_nsect == n_sect){ +- if((frchainP->frch_section.flags & SECTION_TYPE) == S_ZEROFILL) ++ section_type = frchainP->frch_section.flags & SECTION_TYPE; ++ if(section_type == S_ZEROFILL || ++ section_type == S_THREAD_LOCAL_ZEROFILL) + return(0); /* FALSE */ + if(frchainP->frch_last->fr_address == addr) + return(1); /* TRUE */ +@@ -330,9 +446,9 @@ + return(0); /* FALSE */ + } + +-unsigned long ++uint32_t + section_has_fixed_size_data( +-unsigned long n_sect) ++uint32_t n_sect) + { + struct frchain *frchainP; + +Index: odcctools-9.2-ld/include/elf/dwarf2.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ odcctools-9.2-ld/include/elf/dwarf2.h 2013-09-03 21:08:01.897209515 +0000 +@@ -0,0 +1,839 @@ ++/* Declarations and definitions of codes relating to the DWARF2 and ++ DWARF3 symbolic debugging information formats. ++ Copyright (C) 1992, 1993, 1995, 1996, 1997, 1999, 2000, 2001, 2002, ++ 2003, 2004, 2005, 2006 Free Software Foundation, Inc. ++ ++ Written by Gary Funck (gary@intrepid.com) The Ada Joint Program ++ Office (AJPO), Florida State University and Silicon Graphics Inc. ++ provided support for this effort -- June 21, 1995. ++ ++ Derived from the DWARF 1 implementation written by Ron Guilmette ++ (rfg@netcom.com), November 1990. ++ ++ This file is part of GCC. ++ ++ GCC is free software; you can redistribute it and/or modify it under ++ the terms of the GNU General Public License as published by the Free ++ Software Foundation; either version 2, or (at your option) any later ++ version. ++ ++ GCC is distributed in the hope that it will be useful, but WITHOUT ++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public ++ License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with GCC; see the file COPYING. If not, write to the Free ++ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA ++ 02110-1301, USA. */ ++ ++/* This file is derived from the DWARF specification (a public document) ++ Revision 2.0.0 (July 27, 1993) developed by the UNIX International ++ Programming Languages Special Interest Group (UI/PLSIG) and distributed ++ by UNIX International. Copies of this specification are available from ++ UNIX International, 20 Waterview Boulevard, Parsippany, NJ, 07054. ++ ++ This file also now contains definitions from the DWARF 3 specification. */ ++ ++/* This file is shared between GCC and GDB, and should not contain ++ prototypes. */ ++ ++#ifndef _ELF_DWARF2_H ++#define _ELF_DWARF2_H ++ ++/* Structure found in the .debug_line section. */ ++typedef struct ++{ ++ unsigned char li_length [4]; ++ unsigned char li_version [2]; ++ unsigned char li_prologue_length [4]; ++ unsigned char li_min_insn_length [1]; ++ unsigned char li_default_is_stmt [1]; ++ unsigned char li_line_base [1]; ++ unsigned char li_line_range [1]; ++ unsigned char li_opcode_base [1]; ++} ++DWARF2_External_LineInfo; ++ ++typedef struct ++{ ++ unsigned long li_length; ++ unsigned short li_version; ++ unsigned int li_prologue_length; ++ unsigned char li_min_insn_length; ++ unsigned char li_default_is_stmt; ++ int li_line_base; ++ unsigned char li_line_range; ++ unsigned char li_opcode_base; ++} ++DWARF2_Internal_LineInfo; ++ ++/* Structure found in .debug_pubnames section. */ ++typedef struct ++{ ++ unsigned char pn_length [4]; ++ unsigned char pn_version [2]; ++ unsigned char pn_offset [4]; ++ unsigned char pn_size [4]; ++} ++DWARF2_External_PubNames; ++ ++typedef struct ++{ ++ unsigned long pn_length; ++ unsigned short pn_version; ++ unsigned long pn_offset; ++ unsigned long pn_size; ++} ++DWARF2_Internal_PubNames; ++ ++/* Structure found in .debug_info section. */ ++typedef struct ++{ ++ unsigned char cu_length [4]; ++ unsigned char cu_version [2]; ++ unsigned char cu_abbrev_offset [4]; ++ unsigned char cu_pointer_size [1]; ++} ++DWARF2_External_CompUnit; ++ ++typedef struct ++{ ++ unsigned long cu_length; ++ unsigned short cu_version; ++ unsigned long cu_abbrev_offset; ++ unsigned char cu_pointer_size; ++} ++DWARF2_Internal_CompUnit; ++ ++typedef struct ++{ ++ unsigned char ar_length [4]; ++ unsigned char ar_version [2]; ++ unsigned char ar_info_offset [4]; ++ unsigned char ar_pointer_size [1]; ++ unsigned char ar_segment_size [1]; ++} ++DWARF2_External_ARange; ++ ++typedef struct ++{ ++ unsigned long ar_length; ++ unsigned short ar_version; ++ unsigned long ar_info_offset; ++ unsigned char ar_pointer_size; ++ unsigned char ar_segment_size; ++} ++DWARF2_Internal_ARange; ++ ++ ++/* Tag names and codes. */ ++enum dwarf_tag ++ { ++ DW_TAG_padding = 0x00, ++ DW_TAG_array_type = 0x01, ++ DW_TAG_class_type = 0x02, ++ DW_TAG_entry_point = 0x03, ++ DW_TAG_enumeration_type = 0x04, ++ DW_TAG_formal_parameter = 0x05, ++ DW_TAG_imported_declaration = 0x08, ++ DW_TAG_label = 0x0a, ++ DW_TAG_lexical_block = 0x0b, ++ DW_TAG_member = 0x0d, ++ DW_TAG_pointer_type = 0x0f, ++ DW_TAG_reference_type = 0x10, ++ DW_TAG_compile_unit = 0x11, ++ DW_TAG_string_type = 0x12, ++ DW_TAG_structure_type = 0x13, ++ DW_TAG_subroutine_type = 0x15, ++ DW_TAG_typedef = 0x16, ++ DW_TAG_union_type = 0x17, ++ DW_TAG_unspecified_parameters = 0x18, ++ DW_TAG_variant = 0x19, ++ DW_TAG_common_block = 0x1a, ++ DW_TAG_common_inclusion = 0x1b, ++ DW_TAG_inheritance = 0x1c, ++ DW_TAG_inlined_subroutine = 0x1d, ++ DW_TAG_module = 0x1e, ++ DW_TAG_ptr_to_member_type = 0x1f, ++ DW_TAG_set_type = 0x20, ++ DW_TAG_subrange_type = 0x21, ++ DW_TAG_with_stmt = 0x22, ++ DW_TAG_access_declaration = 0x23, ++ DW_TAG_base_type = 0x24, ++ DW_TAG_catch_block = 0x25, ++ DW_TAG_const_type = 0x26, ++ DW_TAG_constant = 0x27, ++ DW_TAG_enumerator = 0x28, ++ DW_TAG_file_type = 0x29, ++ DW_TAG_friend = 0x2a, ++ DW_TAG_namelist = 0x2b, ++ DW_TAG_namelist_item = 0x2c, ++ DW_TAG_packed_type = 0x2d, ++ DW_TAG_subprogram = 0x2e, ++ DW_TAG_template_type_param = 0x2f, ++ DW_TAG_template_value_param = 0x30, ++ DW_TAG_thrown_type = 0x31, ++ DW_TAG_try_block = 0x32, ++ DW_TAG_variant_part = 0x33, ++ DW_TAG_variable = 0x34, ++ DW_TAG_volatile_type = 0x35, ++ /* DWARF 3. */ ++ DW_TAG_dwarf_procedure = 0x36, ++ DW_TAG_restrict_type = 0x37, ++ DW_TAG_interface_type = 0x38, ++ DW_TAG_namespace = 0x39, ++ DW_TAG_imported_module = 0x3a, ++ DW_TAG_unspecified_type = 0x3b, ++ DW_TAG_partial_unit = 0x3c, ++ DW_TAG_imported_unit = 0x3d, ++ DW_TAG_condition = 0x3f, ++ DW_TAG_shared_type = 0x40, ++ /* SGI/MIPS Extensions. */ ++ DW_TAG_MIPS_loop = 0x4081, ++ /* HP extensions. See: ftp://ftp.hp.com/pub/lang/tools/WDB/wdb-4.0.tar.gz . */ ++ DW_TAG_HP_array_descriptor = 0x4090, ++ /* GNU extensions. */ ++ DW_TAG_format_label = 0x4101, /* For FORTRAN 77 and Fortran 90. */ ++ DW_TAG_function_template = 0x4102, /* For C++. */ ++ DW_TAG_class_template = 0x4103, /* For C++. */ ++ DW_TAG_GNU_BINCL = 0x4104, ++ DW_TAG_GNU_EINCL = 0x4105, ++ /* Extensions for UPC. See: http://upc.gwu.edu/~upc. */ ++ DW_TAG_upc_shared_type = 0x8765, ++ DW_TAG_upc_strict_type = 0x8766, ++ DW_TAG_upc_relaxed_type = 0x8767, ++ /* PGI (STMicroelectronics) extensions. No documentation available. */ ++ DW_TAG_PGI_kanji_type = 0xA000, ++ DW_TAG_PGI_interface_block = 0xA020 ++ }; ++ ++#define DW_TAG_lo_user 0x4080 ++#define DW_TAG_hi_user 0xffff ++ ++/* Flag that tells whether entry has a child or not. */ ++#define DW_children_no 0 ++#define DW_children_yes 1 ++ ++/* Form names and codes. */ ++enum dwarf_form ++ { ++ DW_FORM_addr = 0x01, ++ DW_FORM_block2 = 0x03, ++ DW_FORM_block4 = 0x04, ++ DW_FORM_data2 = 0x05, ++ DW_FORM_data4 = 0x06, ++ DW_FORM_data8 = 0x07, ++ DW_FORM_string = 0x08, ++ DW_FORM_block = 0x09, ++ DW_FORM_block1 = 0x0a, ++ DW_FORM_data1 = 0x0b, ++ DW_FORM_flag = 0x0c, ++ DW_FORM_sdata = 0x0d, ++ DW_FORM_strp = 0x0e, ++ DW_FORM_udata = 0x0f, ++ DW_FORM_ref_addr = 0x10, ++ DW_FORM_ref1 = 0x11, ++ DW_FORM_ref2 = 0x12, ++ DW_FORM_ref4 = 0x13, ++ DW_FORM_ref8 = 0x14, ++ DW_FORM_ref_udata = 0x15, ++ DW_FORM_indirect = 0x16 ++ }; ++ ++/* Attribute names and codes. */ ++enum dwarf_attribute ++ { ++ DW_AT_sibling = 0x01, ++ DW_AT_location = 0x02, ++ DW_AT_name = 0x03, ++ DW_AT_ordering = 0x09, ++ DW_AT_subscr_data = 0x0a, ++ DW_AT_byte_size = 0x0b, ++ DW_AT_bit_offset = 0x0c, ++ DW_AT_bit_size = 0x0d, ++ DW_AT_element_list = 0x0f, ++ DW_AT_stmt_list = 0x10, ++ DW_AT_low_pc = 0x11, ++ DW_AT_high_pc = 0x12, ++ DW_AT_language = 0x13, ++ DW_AT_member = 0x14, ++ DW_AT_discr = 0x15, ++ DW_AT_discr_value = 0x16, ++ DW_AT_visibility = 0x17, ++ DW_AT_import = 0x18, ++ DW_AT_string_length = 0x19, ++ DW_AT_common_reference = 0x1a, ++ DW_AT_comp_dir = 0x1b, ++ DW_AT_const_value = 0x1c, ++ DW_AT_containing_type = 0x1d, ++ DW_AT_default_value = 0x1e, ++ DW_AT_inline = 0x20, ++ DW_AT_is_optional = 0x21, ++ DW_AT_lower_bound = 0x22, ++ DW_AT_producer = 0x25, ++ DW_AT_prototyped = 0x27, ++ DW_AT_return_addr = 0x2a, ++ DW_AT_start_scope = 0x2c, ++ DW_AT_stride_size = 0x2e, ++ DW_AT_upper_bound = 0x2f, ++ DW_AT_abstract_origin = 0x31, ++ DW_AT_accessibility = 0x32, ++ DW_AT_address_class = 0x33, ++ DW_AT_artificial = 0x34, ++ DW_AT_base_types = 0x35, ++ DW_AT_calling_convention = 0x36, ++ DW_AT_count = 0x37, ++ DW_AT_data_member_location = 0x38, ++ DW_AT_decl_column = 0x39, ++ DW_AT_decl_file = 0x3a, ++ DW_AT_decl_line = 0x3b, ++ DW_AT_declaration = 0x3c, ++ DW_AT_discr_list = 0x3d, ++ DW_AT_encoding = 0x3e, ++ DW_AT_external = 0x3f, ++ DW_AT_frame_base = 0x40, ++ DW_AT_friend = 0x41, ++ DW_AT_identifier_case = 0x42, ++ DW_AT_macro_info = 0x43, ++ DW_AT_namelist_items = 0x44, ++ DW_AT_priority = 0x45, ++ DW_AT_segment = 0x46, ++ DW_AT_specification = 0x47, ++ DW_AT_static_link = 0x48, ++ DW_AT_type = 0x49, ++ DW_AT_use_location = 0x4a, ++ DW_AT_variable_parameter = 0x4b, ++ DW_AT_virtuality = 0x4c, ++ DW_AT_vtable_elem_location = 0x4d, ++ /* DWARF 3 values. */ ++ DW_AT_allocated = 0x4e, ++ DW_AT_associated = 0x4f, ++ DW_AT_data_location = 0x50, ++ DW_AT_stride = 0x51, ++ DW_AT_entry_pc = 0x52, ++ DW_AT_use_UTF8 = 0x53, ++ DW_AT_extension = 0x54, ++ DW_AT_ranges = 0x55, ++ DW_AT_trampoline = 0x56, ++ DW_AT_call_column = 0x57, ++ DW_AT_call_file = 0x58, ++ DW_AT_call_line = 0x59, ++ DW_AT_description = 0x5a, ++ DW_AT_binary_scale = 0x5b, ++ DW_AT_decimal_scale = 0x5c, ++ DW_AT_small = 0x5d, ++ DW_AT_decimal_sign = 0x5e, ++ DW_AT_digit_count = 0x5f, ++ DW_AT_picture_string = 0x60, ++ DW_AT_mutable = 0x61, ++ DW_AT_threads_scaled = 0x62, ++ DW_AT_explicit = 0x63, ++ DW_AT_object_pointer = 0x64, ++ DW_AT_endianity = 0x65, ++ DW_AT_elemental = 0x66, ++ DW_AT_pure = 0x67, ++ DW_AT_recursive = 0x68, ++ /* SGI/MIPS extensions. */ ++ DW_AT_MIPS_fde = 0x2001, ++ DW_AT_MIPS_loop_begin = 0x2002, ++ DW_AT_MIPS_tail_loop_begin = 0x2003, ++ DW_AT_MIPS_epilog_begin = 0x2004, ++ DW_AT_MIPS_loop_unroll_factor = 0x2005, ++ DW_AT_MIPS_software_pipeline_depth = 0x2006, ++ DW_AT_MIPS_linkage_name = 0x2007, ++ DW_AT_MIPS_stride = 0x2008, ++ DW_AT_MIPS_abstract_name = 0x2009, ++ DW_AT_MIPS_clone_origin = 0x200a, ++ DW_AT_MIPS_has_inlines = 0x200b, ++ /* HP extensions. */ ++ DW_AT_HP_block_index = 0x2000, ++ DW_AT_HP_unmodifiable = 0x2001, /* Same as DW_AT_MIPS_fde. */ ++ DW_AT_HP_actuals_stmt_list = 0x2010, ++ DW_AT_HP_proc_per_section = 0x2011, ++ DW_AT_HP_raw_data_ptr = 0x2012, ++ DW_AT_HP_pass_by_reference = 0x2013, ++ DW_AT_HP_opt_level = 0x2014, ++ DW_AT_HP_prof_version_id = 0x2015, ++ DW_AT_HP_opt_flags = 0x2016, ++ DW_AT_HP_cold_region_low_pc = 0x2017, ++ DW_AT_HP_cold_region_high_pc = 0x2018, ++ DW_AT_HP_all_variables_modifiable = 0x2019, ++ DW_AT_HP_linkage_name = 0x201a, ++ DW_AT_HP_prof_flags = 0x201b, /* In comp unit of procs_info for -g. */ ++ /* GNU extensions. */ ++ DW_AT_sf_names = 0x2101, ++ DW_AT_src_info = 0x2102, ++ DW_AT_mac_info = 0x2103, ++ DW_AT_src_coords = 0x2104, ++ DW_AT_body_begin = 0x2105, ++ DW_AT_body_end = 0x2106, ++ DW_AT_GNU_vector = 0x2107, ++ /* VMS extensions. */ ++ DW_AT_VMS_rtnbeg_pd_address = 0x2201, ++ /* UPC extension. */ ++ DW_AT_upc_threads_scaled = 0x3210, ++ /* PGI (STMicroelectronics) extensions. */ ++ DW_AT_PGI_lbase = 0x3a00, ++ DW_AT_PGI_soffset = 0x3a01, ++ DW_AT_PGI_lstride = 0x3a02, ++ /* Apple extension. */ ++ DW_AT_APPLE_flags = 0x3fe2 ++ }; ++ ++#define DW_AT_lo_user 0x2000 /* Implementation-defined range start. */ ++#define DW_AT_hi_user 0x3ff0 /* Implementation-defined range end. */ ++ ++/* Location atom names and codes. */ ++enum dwarf_location_atom ++ { ++ DW_OP_addr = 0x03, ++ DW_OP_deref = 0x06, ++ DW_OP_const1u = 0x08, ++ DW_OP_const1s = 0x09, ++ DW_OP_const2u = 0x0a, ++ DW_OP_const2s = 0x0b, ++ DW_OP_const4u = 0x0c, ++ DW_OP_const4s = 0x0d, ++ DW_OP_const8u = 0x0e, ++ DW_OP_const8s = 0x0f, ++ DW_OP_constu = 0x10, ++ DW_OP_consts = 0x11, ++ DW_OP_dup = 0x12, ++ DW_OP_drop = 0x13, ++ DW_OP_over = 0x14, ++ DW_OP_pick = 0x15, ++ DW_OP_swap = 0x16, ++ DW_OP_rot = 0x17, ++ DW_OP_xderef = 0x18, ++ DW_OP_abs = 0x19, ++ DW_OP_and = 0x1a, ++ DW_OP_div = 0x1b, ++ DW_OP_minus = 0x1c, ++ DW_OP_mod = 0x1d, ++ DW_OP_mul = 0x1e, ++ DW_OP_neg = 0x1f, ++ DW_OP_not = 0x20, ++ DW_OP_or = 0x21, ++ DW_OP_plus = 0x22, ++ DW_OP_plus_uconst = 0x23, ++ DW_OP_shl = 0x24, ++ DW_OP_shr = 0x25, ++ DW_OP_shra = 0x26, ++ DW_OP_xor = 0x27, ++ DW_OP_bra = 0x28, ++ DW_OP_eq = 0x29, ++ DW_OP_ge = 0x2a, ++ DW_OP_gt = 0x2b, ++ DW_OP_le = 0x2c, ++ DW_OP_lt = 0x2d, ++ DW_OP_ne = 0x2e, ++ DW_OP_skip = 0x2f, ++ DW_OP_lit0 = 0x30, ++ DW_OP_lit1 = 0x31, ++ DW_OP_lit2 = 0x32, ++ DW_OP_lit3 = 0x33, ++ DW_OP_lit4 = 0x34, ++ DW_OP_lit5 = 0x35, ++ DW_OP_lit6 = 0x36, ++ DW_OP_lit7 = 0x37, ++ DW_OP_lit8 = 0x38, ++ DW_OP_lit9 = 0x39, ++ DW_OP_lit10 = 0x3a, ++ DW_OP_lit11 = 0x3b, ++ DW_OP_lit12 = 0x3c, ++ DW_OP_lit13 = 0x3d, ++ DW_OP_lit14 = 0x3e, ++ DW_OP_lit15 = 0x3f, ++ DW_OP_lit16 = 0x40, ++ DW_OP_lit17 = 0x41, ++ DW_OP_lit18 = 0x42, ++ DW_OP_lit19 = 0x43, ++ DW_OP_lit20 = 0x44, ++ DW_OP_lit21 = 0x45, ++ DW_OP_lit22 = 0x46, ++ DW_OP_lit23 = 0x47, ++ DW_OP_lit24 = 0x48, ++ DW_OP_lit25 = 0x49, ++ DW_OP_lit26 = 0x4a, ++ DW_OP_lit27 = 0x4b, ++ DW_OP_lit28 = 0x4c, ++ DW_OP_lit29 = 0x4d, ++ DW_OP_lit30 = 0x4e, ++ DW_OP_lit31 = 0x4f, ++ DW_OP_reg0 = 0x50, ++ DW_OP_reg1 = 0x51, ++ DW_OP_reg2 = 0x52, ++ DW_OP_reg3 = 0x53, ++ DW_OP_reg4 = 0x54, ++ DW_OP_reg5 = 0x55, ++ DW_OP_reg6 = 0x56, ++ DW_OP_reg7 = 0x57, ++ DW_OP_reg8 = 0x58, ++ DW_OP_reg9 = 0x59, ++ DW_OP_reg10 = 0x5a, ++ DW_OP_reg11 = 0x5b, ++ DW_OP_reg12 = 0x5c, ++ DW_OP_reg13 = 0x5d, ++ DW_OP_reg14 = 0x5e, ++ DW_OP_reg15 = 0x5f, ++ DW_OP_reg16 = 0x60, ++ DW_OP_reg17 = 0x61, ++ DW_OP_reg18 = 0x62, ++ DW_OP_reg19 = 0x63, ++ DW_OP_reg20 = 0x64, ++ DW_OP_reg21 = 0x65, ++ DW_OP_reg22 = 0x66, ++ DW_OP_reg23 = 0x67, ++ DW_OP_reg24 = 0x68, ++ DW_OP_reg25 = 0x69, ++ DW_OP_reg26 = 0x6a, ++ DW_OP_reg27 = 0x6b, ++ DW_OP_reg28 = 0x6c, ++ DW_OP_reg29 = 0x6d, ++ DW_OP_reg30 = 0x6e, ++ DW_OP_reg31 = 0x6f, ++ DW_OP_breg0 = 0x70, ++ DW_OP_breg1 = 0x71, ++ DW_OP_breg2 = 0x72, ++ DW_OP_breg3 = 0x73, ++ DW_OP_breg4 = 0x74, ++ DW_OP_breg5 = 0x75, ++ DW_OP_breg6 = 0x76, ++ DW_OP_breg7 = 0x77, ++ DW_OP_breg8 = 0x78, ++ DW_OP_breg9 = 0x79, ++ DW_OP_breg10 = 0x7a, ++ DW_OP_breg11 = 0x7b, ++ DW_OP_breg12 = 0x7c, ++ DW_OP_breg13 = 0x7d, ++ DW_OP_breg14 = 0x7e, ++ DW_OP_breg15 = 0x7f, ++ DW_OP_breg16 = 0x80, ++ DW_OP_breg17 = 0x81, ++ DW_OP_breg18 = 0x82, ++ DW_OP_breg19 = 0x83, ++ DW_OP_breg20 = 0x84, ++ DW_OP_breg21 = 0x85, ++ DW_OP_breg22 = 0x86, ++ DW_OP_breg23 = 0x87, ++ DW_OP_breg24 = 0x88, ++ DW_OP_breg25 = 0x89, ++ DW_OP_breg26 = 0x8a, ++ DW_OP_breg27 = 0x8b, ++ DW_OP_breg28 = 0x8c, ++ DW_OP_breg29 = 0x8d, ++ DW_OP_breg30 = 0x8e, ++ DW_OP_breg31 = 0x8f, ++ DW_OP_regx = 0x90, ++ DW_OP_fbreg = 0x91, ++ DW_OP_bregx = 0x92, ++ DW_OP_piece = 0x93, ++ DW_OP_deref_size = 0x94, ++ DW_OP_xderef_size = 0x95, ++ DW_OP_nop = 0x96, ++ /* DWARF 3 extensions. */ ++ DW_OP_push_object_address = 0x97, ++ DW_OP_call2 = 0x98, ++ DW_OP_call4 = 0x99, ++ DW_OP_call_ref = 0x9a, ++ DW_OP_form_tls_address = 0x9b, ++ DW_OP_call_frame_cfa = 0x9c, ++ DW_OP_bit_piece = 0x9d, ++ /* GNU extensions. */ ++ DW_OP_GNU_push_tls_address = 0xe0, ++ DW_OP_GNU_uninit = 0xf0, ++ /* HP extensions. */ ++ DW_OP_HP_unknown = 0xe0, /* Ouch, the same as GNU_push_tls_address. */ ++ DW_OP_HP_is_value = 0xe1, ++ DW_OP_HP_fltconst4 = 0xe2, ++ DW_OP_HP_fltconst8 = 0xe3, ++ DW_OP_HP_mod_range = 0xe4, ++ DW_OP_HP_unmod_range = 0xe5, ++ DW_OP_HP_tls = 0xe6 ++ }; ++ ++#define DW_OP_lo_user 0xe0 /* Implementation-defined range start. */ ++#define DW_OP_hi_user 0xff /* Implementation-defined range end. */ ++ ++/* Type encodings. */ ++enum dwarf_type ++ { ++ DW_ATE_void = 0x0, ++ DW_ATE_address = 0x1, ++ DW_ATE_boolean = 0x2, ++ DW_ATE_complex_float = 0x3, ++ DW_ATE_float = 0x4, ++ DW_ATE_signed = 0x5, ++ DW_ATE_signed_char = 0x6, ++ DW_ATE_unsigned = 0x7, ++ DW_ATE_unsigned_char = 0x8, ++ /* DWARF 3. */ ++ DW_ATE_imaginary_float = 0x9, ++ DW_ATE_packed_decimal = 0xa, ++ DW_ATE_numeric_string = 0xb, ++ DW_ATE_edited = 0xc, ++ DW_ATE_signed_fixed = 0xd, ++ DW_ATE_unsigned_fixed = 0xe, ++ DW_ATE_decimal_float = 0xf, ++ /* HP extensions. */ ++ DW_ATE_HP_float80 = 0x80, /* Floating-point (80 bit). */ ++ DW_ATE_HP_complex_float80 = 0x81, /* Complex floating-point (80 bit). */ ++ DW_ATE_HP_float128 = 0x82, /* Floating-point (128 bit). */ ++ DW_ATE_HP_complex_float128 = 0x83, /* Complex floating-point (128 bit). */ ++ DW_ATE_HP_floathpintel = 0x84, /* Floating-point (82 bit IA64). */ ++ DW_ATE_HP_imaginary_float80 = 0x85, ++ DW_ATE_HP_imaginary_float128 = 0x86 ++ }; ++ ++#define DW_ATE_lo_user 0x80 ++#define DW_ATE_hi_user 0xff ++ ++/* Decimal sign encodings. */ ++enum dwarf_decimal_sign_encoding ++ { ++ /* DWARF 3. */ ++ DW_DS_unsigned = 0x01, ++ DW_DS_leading_overpunch = 0x02, ++ DW_DS_trailing_overpunch = 0x03, ++ DW_DS_leading_separate = 0x04, ++ DW_DS_trailing_separate = 0x05 ++ }; ++ ++/* Endianity encodings. */ ++enum dwarf_endianity_encoding ++ { ++ /* DWARF 3. */ ++ DW_END_default = 0x00, ++ DW_END_big = 0x01, ++ DW_END_little = 0x02 ++ }; ++ ++#define DW_END_lo_user 0x40 ++#define DW_END_hi_user 0xff ++ ++/* Array ordering names and codes. */ ++enum dwarf_array_dim_ordering ++ { ++ DW_ORD_row_major = 0, ++ DW_ORD_col_major = 1 ++ }; ++ ++/* Access attribute. */ ++enum dwarf_access_attribute ++ { ++ DW_ACCESS_public = 1, ++ DW_ACCESS_protected = 2, ++ DW_ACCESS_private = 3 ++ }; ++ ++/* Visibility. */ ++enum dwarf_visibility_attribute ++ { ++ DW_VIS_local = 1, ++ DW_VIS_exported = 2, ++ DW_VIS_qualified = 3 ++ }; ++ ++/* Virtuality. */ ++enum dwarf_virtuality_attribute ++ { ++ DW_VIRTUALITY_none = 0, ++ DW_VIRTUALITY_virtual = 1, ++ DW_VIRTUALITY_pure_virtual = 2 ++ }; ++ ++/* Case sensitivity. */ ++enum dwarf_id_case ++ { ++ DW_ID_case_sensitive = 0, ++ DW_ID_up_case = 1, ++ DW_ID_down_case = 2, ++ DW_ID_case_insensitive = 3 ++ }; ++ ++/* Calling convention. */ ++enum dwarf_calling_convention ++ { ++ DW_CC_normal = 0x1, ++ DW_CC_program = 0x2, ++ DW_CC_nocall = 0x3, ++ DW_CC_GNU_renesas_sh = 0x40 ++ }; ++ ++#define DW_CC_lo_user 0x40 ++#define DW_CC_hi_user 0xff ++ ++/* Inline attribute. */ ++enum dwarf_inline_attribute ++ { ++ DW_INL_not_inlined = 0, ++ DW_INL_inlined = 1, ++ DW_INL_declared_not_inlined = 2, ++ DW_INL_declared_inlined = 3 ++ }; ++ ++/* Discriminant lists. */ ++enum dwarf_discrim_list ++ { ++ DW_DSC_label = 0, ++ DW_DSC_range = 1 ++ }; ++ ++/* Line number opcodes. */ ++enum dwarf_line_number_ops ++ { ++ DW_LNS_extended_op = 0, ++ DW_LNS_copy = 1, ++ DW_LNS_advance_pc = 2, ++ DW_LNS_advance_line = 3, ++ DW_LNS_set_file = 4, ++ DW_LNS_set_column = 5, ++ DW_LNS_negate_stmt = 6, ++ DW_LNS_set_basic_block = 7, ++ DW_LNS_const_add_pc = 8, ++ DW_LNS_fixed_advance_pc = 9, ++ /* DWARF 3. */ ++ DW_LNS_set_prologue_end = 10, ++ DW_LNS_set_epilogue_begin = 11, ++ DW_LNS_set_isa = 12 ++ }; ++ ++/* Line number extended opcodes. */ ++enum dwarf_line_number_x_ops ++ { ++ DW_LNE_end_sequence = 1, ++ DW_LNE_set_address = 2, ++ DW_LNE_define_file = 3, ++ /* HP extensions. */ ++ DW_LNE_HP_negate_is_UV_update = 0x11, ++ DW_LNE_HP_push_context = 0x12, ++ DW_LNE_HP_pop_context = 0x13, ++ DW_LNE_HP_set_file_line_column = 0x14, ++ DW_LNE_HP_set_routine_name = 0x15, ++ DW_LNE_HP_set_sequence = 0x16, ++ DW_LNE_HP_negate_post_semantics = 0x17, ++ DW_LNE_HP_negate_function_exit = 0x18, ++ DW_LNE_HP_negate_front_end_logical = 0x19, ++ DW_LNE_HP_define_proc = 0x20 ++ }; ++ ++#define DW_LNE_lo_user 0x80 ++#define DW_LNE_hi_user 0xff ++ ++/* Call frame information. */ ++enum dwarf_call_frame_info ++ { ++ DW_CFA_advance_loc = 0x40, ++ DW_CFA_offset = 0x80, ++ DW_CFA_restore = 0xc0, ++ DW_CFA_nop = 0x00, ++ DW_CFA_set_loc = 0x01, ++ DW_CFA_advance_loc1 = 0x02, ++ DW_CFA_advance_loc2 = 0x03, ++ DW_CFA_advance_loc4 = 0x04, ++ DW_CFA_offset_extended = 0x05, ++ DW_CFA_restore_extended = 0x06, ++ DW_CFA_undefined = 0x07, ++ DW_CFA_same_value = 0x08, ++ DW_CFA_register = 0x09, ++ DW_CFA_remember_state = 0x0a, ++ DW_CFA_restore_state = 0x0b, ++ DW_CFA_def_cfa = 0x0c, ++ DW_CFA_def_cfa_register = 0x0d, ++ DW_CFA_def_cfa_offset = 0x0e, ++ /* DWARF 3. */ ++ DW_CFA_def_cfa_expression = 0x0f, ++ DW_CFA_expression = 0x10, ++ DW_CFA_offset_extended_sf = 0x11, ++ DW_CFA_def_cfa_sf = 0x12, ++ DW_CFA_def_cfa_offset_sf = 0x13, ++ DW_CFA_val_offset = 0x14, ++ DW_CFA_val_offset_sf = 0x15, ++ DW_CFA_val_expression = 0x16, ++ /* SGI/MIPS specific. */ ++ DW_CFA_MIPS_advance_loc8 = 0x1d, ++ /* GNU extensions. */ ++ DW_CFA_GNU_window_save = 0x2d, ++ DW_CFA_GNU_args_size = 0x2e, ++ DW_CFA_GNU_negative_offset_extended = 0x2f ++ }; ++ ++#define DW_CIE_ID 0xffffffff ++#define DW_CIE_VERSION 1 ++ ++#define DW_CFA_extended 0 ++#define DW_CFA_lo_user 0x1c ++#define DW_CFA_hi_user 0x3f ++ ++#define DW_CHILDREN_no 0x00 ++#define DW_CHILDREN_yes 0x01 ++ ++#define DW_ADDR_none 0 ++ ++/* Source language names and codes. */ ++enum dwarf_source_language ++ { ++ DW_LANG_C89 = 0x0001, ++ DW_LANG_C = 0x0002, ++ DW_LANG_Ada83 = 0x0003, ++ DW_LANG_C_plus_plus = 0x0004, ++ DW_LANG_Cobol74 = 0x0005, ++ DW_LANG_Cobol85 = 0x0006, ++ DW_LANG_Fortran77 = 0x0007, ++ DW_LANG_Fortran90 = 0x0008, ++ DW_LANG_Pascal83 = 0x0009, ++ DW_LANG_Modula2 = 0x000a, ++ /* DWARF 3. */ ++ DW_LANG_Java = 0x000b, ++ DW_LANG_C99 = 0x000c, ++ DW_LANG_Ada95 = 0x000d, ++ DW_LANG_Fortran95 = 0x000e, ++ DW_LANG_PLI = 0x000f, ++ DW_LANG_ObjC = 0x0010, ++ DW_LANG_ObjC_plus_plus = 0x0011, ++ DW_LANG_UPC = 0x0012, ++ DW_LANG_D = 0x0013, ++ /* MIPS. */ ++ DW_LANG_Mips_Assembler = 0x8001, ++ /* UPC. */ ++ DW_LANG_Upc = 0x8765 ++ }; ++ ++#define DW_LANG_lo_user 0x8000 /* Implementation-defined range start. */ ++#define DW_LANG_hi_user 0xffff /* Implementation-defined range start. */ ++ ++/* Names and codes for macro information. */ ++enum dwarf_macinfo_record_type ++ { ++ DW_MACINFO_define = 1, ++ DW_MACINFO_undef = 2, ++ DW_MACINFO_start_file = 3, ++ DW_MACINFO_end_file = 4, ++ DW_MACINFO_vendor_ext = 255 ++ }; ++ ++/* @@@ For use with GNU frame unwind information. */ ++ ++#define DW_EH_PE_absptr 0x00 ++#define DW_EH_PE_omit 0xff ++ ++#define DW_EH_PE_uleb128 0x01 ++#define DW_EH_PE_udata2 0x02 ++#define DW_EH_PE_udata4 0x03 ++#define DW_EH_PE_udata8 0x04 ++#define DW_EH_PE_sleb128 0x09 ++#define DW_EH_PE_sdata2 0x0A ++#define DW_EH_PE_sdata4 0x0B ++#define DW_EH_PE_sdata8 0x0C ++#define DW_EH_PE_signed 0x08 ++ ++#define DW_EH_PE_pcrel 0x10 ++#define DW_EH_PE_textrel 0x20 ++#define DW_EH_PE_datarel 0x30 ++#define DW_EH_PE_funcrel 0x40 ++#define DW_EH_PE_aligned 0x50 ++ ++#define DW_EH_PE_indirect 0x80 ++ ++#endif /* _ELF_DWARF2_H */ +Index: odcctools-9.2-ld/as/as.h +=================================================================== +--- odcctools-9.2-ld.orig/as/as.h 2013-09-03 21:08:01.409209526 +0000 ++++ odcctools-9.2-ld/as/as.h 2013-09-03 21:08:01.897209515 +0000 +@@ -20,6 +20,13 @@ + #ifndef AS_H_ + #define AS_H_ + ++extern char *apple_flags; ++#define APPLE_INC_VERSION "Apple Inc version" ++/* apple_version is in apple_version.c which is created by the Makefile */ ++extern char apple_version[]; ++/* the GNU version is set in as.c */ ++extern char version_string[]; ++ + #define _(String) (String) + #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) + +@@ -135,6 +142,26 @@ + /* What subseg we are accessing now? */ + extern subsegT now_subseg; + ++/* Type of debugging information we should generate. We currently support ++ stabs, ECOFF, and DWARF2. ++ ++ NOTE! This means debug information about the assembly source code itself ++ and _not_ about possible debug information from a high-level language. ++ This is especially relevant to DWARF2, since the compiler may emit line ++ number directives that the assembler resolves. */ ++ ++enum debug_info_type ++{ ++ DEBUG_UNSPECIFIED, ++ DEBUG_NONE, ++ DEBUG_STABS, ++ DEBUG_ECOFF, ++ DEBUG_DWARF, ++ DEBUG_DWARF2 ++}; ++ ++extern enum debug_info_type debug_type; ++ + /* + * main program "as.c" (command arguments etc) + */ +@@ -155,7 +182,7 @@ + extern char *specific_archflag; + + /* TRUE if the .subsections_via_symbols directive was seen */ +-int subsections_via_symbols; ++extern int subsections_via_symbols; + + /* -I path options for .includes */ + struct directory_stack { +Index: odcctools-9.2-ld/as/frags.c +=================================================================== +--- odcctools-9.2-ld.orig/as/frags.c 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/as/frags.c 2013-09-03 21:08:01.897209515 +0000 +@@ -23,6 +23,7 @@ + #include "obstack.h" + #include "frags.h" + #include "messages.h" ++#include "input-scrub.h" + + struct obstack frags = { 0 }; /* All, and only, frags live here. */ + +@@ -30,6 +31,7 @@ + + fragS zero_address_frag = { + 0, /* fr_address */ ++ 0, /* last_fr_address */ + NULL, /* fr_next */ + 0, /* fr_fix */ + 0, /* fr_var */ +@@ -38,7 +40,11 @@ + NULL, /* fr_opcode */ + rs_fill, /* fr_type */ + 0, /* fr_subtype */ ++#ifdef ARM ++ 0 /* fr_literal [0] */ ++#else + {0} /* fr_literal [0] */ ++#endif + }; + + +@@ -61,13 +67,14 @@ + } + if ((int)(obstack_room(&frags)) < nchars) { + unsigned int n,oldn; +- long oldc; ++ int32_t oldc; + + frag_wane (frag_now); + frag_new (0); + oldn=(unsigned)-1; + oldc=frags.chunk_size; +- frags.chunk_size=2*nchars; ++ if(2*nchars > oldc) ++ frags.chunk_size=2*nchars; + while((int)(n=obstack_room(&frags)) < nchars && n < oldn) { + frag_wane(frag_now); + frag_new(0); +@@ -104,7 +111,7 @@ + register fragS * former_last_fragP; + /* char *throw_away_pointer; JF unused */ + register frchainS * frchP; +- long tmp; /* JF */ ++ int32_t tmp; /* JF */ + + if(frags.chunk_size == 0){ + know(flagseen['n']); +@@ -116,7 +123,7 @@ + (frag_now->fr_literal) - old_frags_var_max_size; + /* Fix up old frag's fr_fix. */ + +- obstack_finish (&frags); ++ (void)obstack_finish (&frags); + /* This will align the obstack so the */ + /* next struct we allocate on it will */ + /* begin at a correct boundary. */ +@@ -190,11 +197,14 @@ + int var, + relax_substateT subtype, + symbolS *symbol, +-long offset, ++int32_t offset, + char *opcode) + { + register char *retval; + ++#ifdef ARM ++ as_file_and_line (&frag_now->fr_file, &frag_now->fr_line); ++#endif /* ARM */ + frag_grow (max_chars); + retval = obstack_next_free (&frags); + obstack_blank_fast (&frags, max_chars); +@@ -205,6 +215,9 @@ + frag_now->fr_offset = offset; + frag_now->fr_opcode = opcode; + frag_new (max_chars); ++#ifdef ARM ++ as_file_and_line (&frag_now->fr_file, &frag_now->fr_line); ++#endif /* ARM */ + return (retval); + } /* frag_var() */ + +@@ -272,7 +285,7 @@ + fill_size, /* var */ + (relax_substateT)max_bytes_to_fill,/* subtype */ + (symbolS *)0, /* symbol */ +- (long)power_of_2_alignment, /* offset */ ++ (int32_t)power_of_2_alignment, /* offset */ + (char *)0); /* opcode */ + if(fill_size == 1 || fill_size == 2 || fill_size == 4) + memcpy(fr_literal, fill, fill_size); +Index: odcctools-9.2-ld/as/frags.h +=================================================================== +--- odcctools-9.2-ld.orig/as/frags.h 2013-09-03 21:08:01.405209526 +0000 ++++ odcctools-9.2-ld/as/frags.h 2013-09-03 21:08:01.901209515 +0000 +@@ -41,27 +41,38 @@ + */ + struct frag /* a code fragment */ + { +- unsigned long fr_address; /* Object file address. */ ++ uint64_t fr_address; /* Object file address. */ ++ uint64_t last_fr_address; /* When relaxing multiple times, remember the */ ++ /* address the frag had in the last relax pass*/ + struct frag *fr_next; /* Chain forward; ascending address order. */ + /* Rooted in frch_root. */ + +- long fr_fix; /* (Fixed) number of chars we know we have. */ ++ int32_t fr_fix; /* (Fixed) number of chars we know we have. */ + /* May be 0. */ +- long fr_var; /* (Variable) number of chars after above. */ ++ int32_t fr_var; /* (Variable) number of chars after above. */ + /* May be 0. */ + struct symbol *fr_symbol; /* For variable-length tail. */ +- long fr_offset; /* For variable-length tail. */ ++ int32_t fr_offset; /* For variable-length tail. */ + char *fr_opcode; /* ->opcode low addr byte,for relax()ation*/ + relax_stateT fr_type; /* What state is my tail in? */ + relax_substateT fr_subtype; /* Used to index in to md_relax_table for */ + /* fr_type == rs_machine_dependent frags. */ ++#ifdef ARM ++ /* Where the frag was created, or where it became a variant frag. */ ++ char *fr_file; ++ unsigned int fr_line; ++ /* Flipped each relax pass so we can easily determine whether ++ fr_address has been adjusted. */ ++ unsigned int relax_marker:1, ++ pad:31; ++#endif /* ARM */ + char fr_literal[1]; /* Chars begin here. */ + /* One day we will compile fr_literal[0]. */ + }; + + /* We want to say fr_literal[0] below */ + #define SIZEOF_STRUCT_FRAG \ +- ((int)zero_address_frag.fr_literal - (int)&zero_address_frag) ++ ((uintptr_t)zero_address_frag.fr_literal - (uintptr_t)&zero_address_frag) + + /* + * frag_now points at the current frag we are building. This frag is incomplete. +@@ -93,7 +104,7 @@ + int var, + relax_substateT subtype, + symbolS *symbol, +- long offset, ++ int32_t offset, + char *opcode); + extern void frag_wane( + fragS *fragP); +@@ -114,6 +125,6 @@ + frag_wane (frag_now); \ + frag_new (0); \ + } \ +- obstack_1grow( &frags, datum ); \ ++ (void)obstack_1grow( &frags, datum ); \ + } + #endif /* _FRAGS_H_ */ +Index: odcctools-9.2-ld/as/input-file.c +=================================================================== +--- odcctools-9.2-ld.orig/as/input-file.c 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/as/input-file.c 2013-09-03 21:08:01.901209515 +0000 +@@ -147,11 +147,13 @@ + + char * + input_file_give_next_buffer( +-char *where) /* Where to place 1st character of new buffer. */ ++char *where, /* Where to place 1st character of new buffer. */ ++int *give_next_size) + { + char * return_value; /* -> Last char of what we read, + 1. */ + register int size; + ++ *give_next_size = BUFFER_SIZE; + if (f_in == (FILE *)0) + return 0; + /* +Index: odcctools-9.2-ld/as/input-file.h +=================================================================== +--- odcctools-9.2-ld.orig/as/input-file.h 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/as/input-file.h 2013-09-03 21:08:01.901209515 +0000 +@@ -34,14 +34,16 @@ + * + * input_file_open(name) Call once for each input file. + * +- * input_file_give_next_buffer(where) Call once to get each new buffer. +- * Return 0: no more chars left in file, ++ * input_file_give_next_buffer(where, Call once to get each new buffer. ++ * give_next_size) Return 0: no more chars left in file, + * the file has already been closed. + * Otherwise: return a pointer to just + * after the last character we read + * into the buffer. + * If we can only read 0 characters, then + * end-of-file is faked. ++ * give_next_size is the BUFFER_SIZE it ++ * will use next. + * + * All errors are reported (using as_perror) so caller doesn't have to think + * about I/O errors. No I/O errors are fatal: an end-of-file may be faked. +@@ -65,4 +67,5 @@ + char *filename, + int pre); + extern char *input_file_give_next_buffer( +- char *where); ++ char *where, ++ int *give_next_size); +Index: odcctools-9.2-ld/as/input-scrub.c +=================================================================== +--- odcctools-9.2-ld.orig/as/input-scrub.c 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/as/input-scrub.c 2013-09-03 21:08:01.901209515 +0000 +@@ -113,7 +113,7 @@ + + buffer_length = input_file_buffer_size (); + +- buffer_start = xmalloc ((long)(BEFORE_SIZE + buffer_length + buffer_length + AFTER_SIZE)); ++ buffer_start = xmalloc ((size_t)(BEFORE_SIZE + buffer_length + buffer_length + AFTER_SIZE)); + memcpy(buffer_start, BEFORE_STRING, (int)BEFORE_SIZE); + + /* Line number things. */ +@@ -177,6 +177,7 @@ + char **bufp) + { + register char * limit; /* -> just after last char of buffer. */ ++ int give_next_size; + + if (partial_size) + { +@@ -184,11 +185,12 @@ + memcpy(buffer_start + BEFORE_SIZE, save_source, (int)AFTER_SIZE); + } + get_more: +- limit = input_file_give_next_buffer (buffer_start + BEFORE_SIZE + partial_size); ++ limit = input_file_give_next_buffer( ++ buffer_start + BEFORE_SIZE + partial_size, ++ &give_next_size); + if (limit) + { + register char * p; /* Find last newline. */ +- + for (p = limit; * -- p != '\n'; ) + { + } +@@ -199,9 +201,19 @@ + + new = limit - (buffer_start + BEFORE_SIZE + partial_size); + partial_size += new; ++ ++ /* ++ * If there is enough room left in this buffer for what ++ * input_file_give_next_buffer() will need don't reallocate as we ++ * could run out of memory needlessly. ++ */ ++ if((BEFORE_SIZE + buffer_length * 2) - (limit - buffer_start) > ++ give_next_size) ++ goto get_more; ++ + buffer_length = buffer_length * 2; + buffer_start = xrealloc (buffer_start, +- (long)(BEFORE_SIZE + buffer_length + ++ (size_t)(BEFORE_SIZE + buffer_length + + buffer_length + AFTER_SIZE)); + *bufp = buffer_start + BEFORE_SIZE; + goto get_more; +@@ -392,30 +404,11 @@ + + #ifdef NeXT_MOD /* .include feature */ + /* DJA -- added for .include pseudo op support */ +-void +-read_an_include_file( ++char * ++find_an_include_file( + char *no_path_name) + { +- char * buffer; +- char * last_buffer_limit; +- char * last_buffer_start; +- int last_doing_include; +- FILE * last_f_in; +- char * last_file_name; +- char * last_input_line_pointer; +- char * last_logical_input_file; +- line_numberT last_logical_input_line; +- int last_partial_size; +- char * last_partial_where; +- char * last_physical_input_file; +- line_numberT last_physical_input_line; +- char last_save_source [AFTER_SIZE]; +- int last_buffer_length; +-#if 0 +- char * last_save_buffer; +-#endif + char name_buffer [MAXPATHLEN]; +- scrub_context_data scrub_context; + register struct directory_stack * the_path_pointer; + register char * whole_file_name; + +@@ -471,9 +464,42 @@ + the_path_pointer++; + } + as_fatal ("Couldn't find the include file: \"%s\"", no_path_name); +- return; ++ return (NULL); + } + found: ++ return (whole_file_name); ++} ++ ++void ++read_an_include_file( ++char *no_path_name) ++{ ++ char * buffer; ++ char * last_buffer_limit; ++ char * last_buffer_start; ++ int last_doing_include; ++ FILE * last_f_in; ++ char * last_file_name; ++ char * last_input_line_pointer; ++ char * last_logical_input_file; ++ line_numberT last_logical_input_line; ++ int last_partial_size; ++ char * last_partial_where; ++ char * last_physical_input_file; ++ line_numberT last_physical_input_line; ++ char last_save_source [AFTER_SIZE]; ++ int last_buffer_length; ++#if 0 ++ char * last_save_buffer; ++#endif ++ scrub_context_data scrub_context; ++ register char * whole_file_name; ++ ++ /* ++ * figure out what directory the file name is in. ++ */ ++ whole_file_name = find_an_include_file (no_path_name); ++ + /* + * save a copy of the file state for a recursive call to read a file + */ +Index: odcctools-9.2-ld/as/input-scrub.h +=================================================================== +--- odcctools-9.2-ld.orig/as/input-scrub.h 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/as/input-scrub.h 2013-09-03 21:08:01.901209515 +0000 +@@ -45,5 +45,7 @@ + char *filename); + extern char *input_scrub_next_buffer( + char **bufp); ++extern char *find_an_include_file( ++ char *no_path_name); + extern void read_an_include_file( + char *no_path_name); +Index: odcctools-9.2-ld/as/layout.c +=================================================================== +--- odcctools-9.2-ld.orig/as/layout.c 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/as/layout.c 2013-09-03 21:08:01.901209515 +0000 +@@ -30,6 +30,7 @@ + #include "md.h" + #include "obstack.h" + #include "input-scrub.h" ++#include "dwarf2dbg.h" + #if I386 + #include "i386.h" + #endif +@@ -67,6 +68,8 @@ + (0) + #endif + ++extern int arm_relax_frag (int nsect, fragS *fragp, int32_t stretch); ++ + #endif /* ARM */ + + /* FROM write.c line 96 */ +@@ -77,15 +80,79 @@ + static void fixup_section( + fixS *fixP, + int nsect); +-static void relax_section( ++#ifndef SPARC ++static int is_assembly_time_constant_subtraction_expression( ++ symbolS *add_symbolP, ++ int add_symbol_nsect, ++ symbolS *sub_symbolP, ++ int sub_symbol_nsect); ++#endif /* !defined(SPARC) */ ++static int relax_section( + struct frag *section_frag_root, + int nsect); + static relax_addressT relax_align( + relax_addressT address, +- long alignment); ++ uint32_t alignment); ++#ifndef ARM + static int is_down_range( + struct frag *f1, + struct frag *f2); ++#endif /* !defined(ARM) */ ++ ++/* ++ * add_last_frags_to_sections() does what layout_addresses() does below about ++ * adding a last ".fill 0" frag to each section. This is called by ++ * dwarf2_finish() allow get_frag_fix() in dwarf2dbg.c to work for the last ++ * fragment in a section. ++ */ ++void ++add_last_frags_to_sections( ++void) ++{ ++ struct frchain *frchainP; ++ ++ if(frchain_root == NULL) ++ return; ++ ++ /* ++ * If there is any current frag close it off. ++ */ ++ if(frag_now != NULL && frag_now->fr_fix == 0){ ++ frag_now->fr_fix = obstack_next_free(&frags) - ++ frag_now->fr_literal; ++ frag_wane(frag_now); ++ } ++ ++ /* ++ * For every section, add a last ".fill 0" frag that will later be used ++ * as the ending address of that section. ++ */ ++ for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){ ++ /* ++ * We must do the obstack_finish(), so the next object we put on ++ * obstack frags will not appear to start at the fr_literal of the ++ * current frag. Also, it ensures that the next object will begin ++ * on a address that is aligned correctly for the engine that runs ++ * the assembler. ++ */ ++ (void)obstack_finish(&frags); ++ ++ /* ++ * Make a fresh frag for the last frag. ++ */ ++ frag_now = (fragS *)obstack_alloc(&frags, SIZEOF_STRUCT_FRAG); ++ memset(frag_now, '\0', SIZEOF_STRUCT_FRAG); ++ frag_now->fr_next = NULL; ++ (void)obstack_finish(&frags); ++ ++ /* ++ * Append the new frag to current frchain. ++ */ ++ frchainP->frch_last->fr_next = frag_now; ++ frchainP->frch_last = frag_now; ++ frag_wane(frag_now); ++ } ++} + + /* + * layout_addresses() is called after all the assembly code has been read and +@@ -101,8 +168,10 @@ + fragS *fragP; + relax_addressT slide, tmp; + symbolS *symbolP; +- unsigned long nbytes, fill_size, repeat_expression, partial_bytes; ++ uint32_t nbytes, fill_size, repeat_expression, partial_bytes, layout_pass; ++ uint32_t section_type; + relax_stateT old_fr_type; ++ int changed; + + if(frchain_root == NULL) + return; +@@ -128,7 +197,7 @@ + * on a address that is aligned correctly for the engine that runs + * the assembler. + */ +- obstack_finish(&frags); ++ (void)obstack_finish(&frags); + + /* + * Make a fresh frag for the last frag. +@@ -136,7 +205,7 @@ + frag_now = (fragS *)obstack_alloc(&frags, SIZEOF_STRUCT_FRAG); + memset(frag_now, '\0', SIZEOF_STRUCT_FRAG); + frag_now->fr_next = NULL; +- obstack_finish(&frags); ++ (void)obstack_finish(&frags); + + /* + * Append the new frag to current frchain. +@@ -152,18 +221,47 @@ + * relaxing each section. That is all sections will start at address + * zero and addresses of the frags in that section will increase from + * there. ++ * ++ * The debug sections are done last as other section are needed to be ++ * done first becase debug sections may have line numbers with .loc ++ * directives in them and their sizes need to be set before processing ++ * the line number sections. We also do sections that have rs_leb128s ++ * in them before debug sections but after other sections since they ++ * are used for things like exception tables and they may be refering to ++ * sections such that their sizes too must be known first. + */ + for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){ +- if((frchainP->frch_section.flags & SECTION_TYPE) == S_ZEROFILL) +- continue; +- /* +- * This is done so in case md_estimate_size_before_relax() (called +- * by relax_section) wants to make fixSs they are for this +- * section. +- */ +- frchain_now = frchainP; ++ if((frchainP->frch_section.flags & S_ATTR_DEBUG) == S_ATTR_DEBUG) ++ frchainP->layout_pass = 2; ++ else if(frchainP->has_rs_leb128s == TRUE) ++ frchainP->layout_pass = 1; ++ else ++ frchainP->layout_pass = 0; ++ } ++ for(layout_pass = 0; layout_pass < 3; layout_pass++){ ++ do{ ++ changed = 0; ++ for(frchainP = frchain_root; ++ frchainP; ++ frchainP = frchainP->frch_next){ ++ if(frchainP->layout_pass != layout_pass) ++ continue; ++ section_type = frchainP->frch_section.flags & SECTION_TYPE; ++ if(section_type == S_ZEROFILL || ++ section_type == S_THREAD_LOCAL_ZEROFILL) ++ continue; ++ /* ++ * This is done so in case md_estimate_size_before_relax() ++ * (called by relax_section) wants to make fixSs they are ++ * for this section. ++ */ ++ frchain_now = frchainP; + +- relax_section(frchainP->frch_root, frchainP->frch_nsect); ++ changed += relax_section(frchainP->frch_root, ++ frchainP->frch_nsect); ++ } ++ } ++ while(changed != 0); + } + + /* +@@ -173,7 +271,9 @@ + */ + slide = 0; + for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){ +- if((frchainP->frch_section.flags & SECTION_TYPE) == S_ZEROFILL) ++ section_type = frchainP->frch_section.flags & SECTION_TYPE; ++ if(section_type == S_ZEROFILL || ++ section_type == S_THREAD_LOCAL_ZEROFILL) + continue; + slide = round(slide, 1 << frchainP->frch_section.align); + tmp = frchainP->frch_last->fr_address; +@@ -192,7 +292,9 @@ + * is that section numbers do not end up in address order. + */ + for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){ +- if((frchainP->frch_section.flags & SECTION_TYPE) != S_ZEROFILL) ++ section_type = frchainP->frch_section.flags & SECTION_TYPE; ++ if(section_type != S_ZEROFILL && ++ section_type != S_THREAD_LOCAL_ZEROFILL) + continue; + slide = round(slide, 1 << frchainP->frch_section.align); + +@@ -248,8 +350,8 @@ + nbytes = fragP->fr_next->fr_address - + fragP->fr_address - + fragP->fr_fix; +- if(nbytes < 0){ +- as_warn("rs_org invalid, dot past value by %ld bytes", ++ if((int)nbytes < 0){ ++ as_warn("rs_org invalid, dot past value by %d bytes", + nbytes); + nbytes = 0; + } +@@ -322,6 +424,49 @@ + frag_wane(fragP); + break; + ++ case rs_dwarf2dbg: ++ dwarf2dbg_convert_frag(fragP); ++ break; ++ ++ case rs_leb128: ++ { ++ int size; ++#ifdef OLD ++ valueT value = S_GET_VALUE (fragP->fr_symbol); ++#else ++ valueT value; ++ expressionS *expression; ++ ++ if(fragP->fr_symbol->expression != NULL){ ++ expression = ++ (expressionS *)fragP->fr_symbol->expression; ++ value = 0; ++ if(expression->X_add_symbol != NULL) ++ value += expression->X_add_symbol->sy_nlist.n_value; ++ if(expression->X_subtract_symbol != NULL) ++ value -= ++ expression->X_subtract_symbol->sy_nlist.n_value; ++ value += expression->X_add_number; ++ } ++ else{ ++ value = fragP->fr_symbol->sy_nlist.n_value + ++ fragP->fr_address; ++ } ++#endif ++ ++ size = output_leb128 (fragP->fr_literal + fragP->fr_fix, ++ value, ++ fragP->fr_subtype); ++ ++ fragP->fr_fix += size; ++ fragP->fr_type = rs_fill; ++ fragP->fr_var = 0; ++ fragP->fr_offset = 0; ++ fragP->fr_symbol = NULL; ++ } ++ break; ++ ++ + default: + BAD_CASE(fragP->fr_type); + break; +@@ -352,10 +497,10 @@ + { + symbolS *add_symbolP; + symbolS *sub_symbolP; +- long value; ++ signed_expr_t value; + int size; + char *place; +- long where; ++ int32_t where; + char pcrel; + fragS *fragP; + int add_symbol_N_TYPE; +@@ -399,7 +544,6 @@ + /* If the symbol is defined in this file, the linker won't set the + low-order bit for a Thumb symbol, so we have to do it here. */ + if(add_symbolP != NULL && add_symbolP->sy_desc & N_ARM_THUMB_DEF && +- !(add_symbolP->sy_desc & N_WEAK_DEF) && + !(sub_symbolP != NULL && sub_symbolP->sy_desc & N_ARM_THUMB_DEF) && + !pcrel){ + value |= 1; +@@ -452,6 +596,20 @@ + */ + else if((sub_symbolP->sy_type & N_TYPE) == N_SECT && + (add_symbolP->sy_type & N_TYPE) == N_SECT){ ++#if defined(I386) && !defined(ARCH64) ++ /* ++ * For 'symbol@TLVP - subtract_symbol' type relocations the ++ * subtract_symbol value is stored in the contents of the ++ * item to be relocated. ++ */ ++ if(fixP->fx_r_type == GENERIC_RELOC_TLV){ ++ value += fixP->fx_frag->fr_address + where + ++ fixP->fx_size - sub_symbolP->sy_value; ++ fixP->fx_subsy = NULL; /* no SECTDIFF reloc entry */ ++ fixP->fx_pcrel = TRUE; /* force pcrel */ ++ goto down; ++ } ++#endif + /* + * We are use the new features that are incompatible with + * 3.2 then just calculate the value and let this create a +@@ -474,7 +632,7 @@ + } + else{ + as_warn("Can't emit reloc type %u {-symbol \"%s\"} " +- "@ file address %ld (mode?).", ++ "@ file address %llu (mode?).", + fixP->fx_r_type, sub_symbolP->sy_name, + fragP->fr_address + where); + } +@@ -488,13 +646,60 @@ + * the difference between the two symbols because + * that's handled by the subtractor/vanilla reloc pair. + */ +- value += add_symbolP->sy_value - sub_symbolP->sy_value; ++ value += add_symbolP->sy_value; ++ value -= sub_symbolP->sy_value; ++#else ++ /* ++ * But for x86_64 expressions in the debug section must ++ * be the actual value of the expression. ++ */ ++ if(is_section_debug(nsect)){ ++ value += add_symbolP->sy_value; ++ value -= sub_symbolP->sy_value; ++ } + #endif + sub_symbol_nsect = sub_symbolP->sy_other; ++ /* ++ * If we have the special assembly time constant expression ++ * of the difference of two symbols defined in the same ++ * section then divided by exactly 2 adjust the value and ++ * make sure these symbols will produce an assembly time ++ * constant. ++ */ ++ if(fixP->fx_sectdiff_divide_by_two == 1){ ++ value = value / 2; ++ if(is_assembly_time_constant_subtraction_expression( ++ add_symbolP, add_symbol_nsect, ++ sub_symbolP, sub_symbol_nsect) == TRUE){ ++ fixP->fx_addsy = NULL; /* no relocation entry */ ++ goto down; ++ } ++ else{ ++ layout_line = fixP->line; ++ layout_file = fixP->file; ++ as_warn("section difference divide by two " ++ "expression, \"%s\" minus \"%s\" divide by " ++ "2 will not produce an assembly time " ++ "constant", add_symbolP->sy_name, ++ sub_symbolP->sy_name); ++ } ++ } + if(is_end_section_address(add_symbol_nsect, + add_symbolP->sy_value) || + is_end_section_address(sub_symbol_nsect, + sub_symbolP->sy_value)){ ++ if(is_assembly_time_constant_subtraction_expression( ++ add_symbolP, add_symbol_nsect, ++ sub_symbolP, sub_symbol_nsect) == TRUE){ ++ fixP->fx_addsy = NULL; /* no relocation entry */ ++ goto down; ++ } ++ if(is_section_debug(nsect) && ++ strcmp(add_symbolP->sy_name, FAKE_LABEL_NAME) == 0 && ++ strcmp(sub_symbolP->sy_name, FAKE_LABEL_NAME) == 0){ ++ fixP->fx_addsy = NULL; /* no relocation entry */ ++ goto down; ++ } + layout_line = fixP->line; + layout_file = fixP->file; + as_warn("section difference relocatable subtraction " +@@ -521,6 +726,19 @@ + value -= sub_symbolP->sy_value; + fixP->fx_subsy = NULL; /* no SECTDIFF relocation entry */ + } ++#if defined(I386) && !defined(ARCH64) ++ /* ++ * For 'symbol@TLVP - subtract_symbol' type relocations the ++ * subtract_symbol value is stored in the contents of the item ++ * to be relocated. ++ */ ++ else if(fixP->fx_r_type == GENERIC_RELOC_TLV){ ++ value += fixP->fx_frag->fr_address + where + fixP->fx_size - ++ sub_symbolP->sy_value; ++ fixP->fx_subsy = NULL; /* no SECTDIFF relocation entry */ ++ fixP->fx_pcrel = TRUE; /* force pcrel */ ++ } ++#endif + /* + * At this point we have something we can't generate a + * relocation entry for (two undefined symbols, etc.). +@@ -568,7 +786,7 @@ + value += add_symbolP->sy_value; + #ifdef ARM + /* FROM write.c line 2667 */ +- value -= where + fragP->fr_address; ++ value -= MD_PCREL_FROM_SECTION (fixP, nsect); + #else + value -= size + where + fragP->fr_address; + #endif +@@ -623,9 +841,15 @@ + is_local_symbol(add_symbolP) && + !is_section_cstring_literals(add_symbol_nsect)) ) + #else +- if((add_symbolP->sy_type & N_EXT) != N_EXT || +- add_symbol_N_TYPE != N_SECT || +- !is_section_coalesced(add_symbol_nsect)) ++ if(((add_symbolP->sy_type & N_EXT) != N_EXT || ++ add_symbol_N_TYPE != N_SECT || ++ !is_section_coalesced(add_symbol_nsect)) && ++ (add_symbolP->sy_desc & N_WEAK_DEF) != N_WEAK_DEF ++#if defined(I386) && !defined(ARCH64) ++ && ++ fixP->fx_r_type != GENERIC_RELOC_TLV ++#endif ++ ) + #endif + value += add_symbolP->sy_value; + break; +@@ -662,10 +886,15 @@ + + if((size == 1 && (value & 0xffffff00) && + ((value & 0xffffff80) != 0xffffff80)) || +- (size == 2 && (value & 0xffff8000) && +- ((value & 0xffff8000) != 0xffff8000))) +- as_bad("Fixup of %ld too large for field width of %d", ++ (size == 2 && (value & 0xffff0000) && ++ ((value & 0xffff8000) != 0xffff8000))){ ++ layout_line = fixP->line; ++ layout_file = fixP->file; ++ as_bad("Fixup of %lld too large for field width of %d", + value, size); ++ layout_line = 0; ++ layout_file = NULL; ++ } + + /* + * Now place the fix expression's value in the place for the size. +@@ -702,6 +931,134 @@ + } + } + ++#ifndef SPARC ++/* ++ * is_assembly_time_constant_subtraction_expression() is passed the symbols and ++ * section numbers of a subtraction expression invloving symbols both defined in ++ * some section. If the subtraction expression is an assembly time constant ++ * value then this returns 1 (TRUE) else this returns 0 (FALSE). ++ * ++ * Since the static link editor can break apart a section this routine can only ++ * return TRUE when it is known for sure these symbols will not be moved apart ++ * from each other. So this is an assembly time constant subtraction expression ++ * if the following are all true: ++ * - the expression's symbols are assembly temporary symbols (starting with 'L') ++ * - assembly temporary symbol are not being saved (no -L flag) ++ * - the two symbols are in the same section ++ * - the section is a regular section or coalesced section (non-literal section) ++ * - there are no non-assembly temporary symbols defined between two symbols of ++ * the expression. For example if the assembly code is: ++ * L1: nop ++ * foo: nop ++ * L2: nop ++ * the expression is L1-L2 is not an assembly time constant because the block ++ * of code after foo (including the address of L2) could be link edited away ++ * from the block of code with L1. ++ */ ++static ++int ++is_assembly_time_constant_subtraction_expression( ++symbolS *add_symbolP, ++int add_symbol_nsect, ++symbolS *sub_symbolP, ++int sub_symbol_nsect) ++{ ++ struct frchain *frchainP; ++ uint32_t section_type, section_attributes; ++ symbolS *prev_symbol; ++ int non_assembly_temporary_symbol; ++ ++ /* see if both symbols are assembly temporary symbols */ ++ if(add_symbolP->sy_name == NULL || add_symbolP->sy_name[0] != 'L' || ++ sub_symbolP->sy_name == NULL || sub_symbolP->sy_name[0] != 'L') ++ return(0); ++ ++ /* make sure we are not saving assembly temporary symbols */ ++ if(flagseen[(int)'L']) ++ return(0); ++ ++ /* make sure the two symbols are in the same section */ ++ if(add_symbol_nsect != sub_symbol_nsect) ++ return(0); ++ ++ /* make sure the section is a regular or coalesced section */ ++ section_attributes = 0; ++ for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){ ++ if(frchainP->frch_nsect == add_symbol_nsect){ ++ section_type = frchainP->frch_section.flags & SECTION_TYPE; ++ section_attributes = frchainP->frch_section.flags & ++ SECTION_ATTRIBUTES; ++ if(section_type == S_REGULAR || section_type == S_COALESCED) ++ break; ++ else ++ return(0); ++ } ++ } ++ ++ /* ++ * See if we can find the chain of symbols from the add_symbolP through ++ * its previous symbols to the sub_symbolP. And check for non assembler ++ * temporary symbols along that chain. ++ */ ++ non_assembly_temporary_symbol = 0; ++ for(prev_symbol = add_symbolP->sy_prev_by_index; ++ prev_symbol != NULL; ++ prev_symbol = prev_symbol->sy_prev_by_index){ ++ if((prev_symbol->sy_type & N_SECT) == N_SECT && ++ (prev_symbol->sy_type & N_STAB) == 0 && ++ prev_symbol->sy_other == add_symbol_nsect){ ++ if(prev_symbol == sub_symbolP){ ++ if(non_assembly_temporary_symbol == 0) ++ return(1); ++ else ++ return(0); ++ } ++ if(prev_symbol->sy_name != NULL && ++ prev_symbol->sy_name[0] != 'L') ++ non_assembly_temporary_symbol = 1; ++ } ++ } ++ ++ /* ++ * Couldn't find the chain above, so now try we can find the chain of ++ * symbols from the sub_symbolP through its previous symbols to the ++ * add_symbolP. And check for non assembler temporary symbols along ++ * that chain. ++ */ ++ non_assembly_temporary_symbol = 0; ++ for(prev_symbol = sub_symbolP->sy_prev_by_index; ++ prev_symbol != NULL; ++ prev_symbol = prev_symbol->sy_prev_by_index){ ++ if((prev_symbol->sy_type & N_SECT) == N_SECT && ++ (prev_symbol->sy_type & N_STAB) == 0 && ++ prev_symbol->sy_other == sub_symbol_nsect){ ++ if(prev_symbol == add_symbolP){ ++ if(non_assembly_temporary_symbol == 0) ++ return(1); ++ else ++ return(0); ++ } ++ if(prev_symbol->sy_name != NULL && ++ prev_symbol->sy_name[0] != 'L') ++ non_assembly_temporary_symbol = 1; ++ } ++ } ++ ++ /* ++ * It is possible that this expression is coming from a dwarf section ++ * made from .file and .loc directives. If so both symbols would have ++ * the FAKE_LABEL_NAME and the section_type would be ++ * and in this case the then the expression is an assembly time ++ * constant. ++ */ ++ if((section_attributes & S_ATTR_DEBUG) == S_ATTR_DEBUG && ++ strcmp(add_symbolP->sy_name, FAKE_LABEL_NAME) == 0 && ++ strcmp(sub_symbolP->sy_name, FAKE_LABEL_NAME) == 0) ++ return(1); ++ ++ return(0); ++} ++#endif /* !defined(SPARC) */ + + /* + * relax_section() here we set the fr_address values in the frags. +@@ -711,7 +1068,7 @@ + * are know then they can be slid to their final address. + */ + static +-void ++int + relax_section( + struct frag *frag_root, + int nsect) +@@ -719,30 +1076,34 @@ + struct frag *fragP; + relax_addressT address; + +- long stretch; /* May be any size, 0 or negative. */ +- /* Cumulative number of addresses we have */ +- /* relaxed this pass. */ +- /* We may have relaxed more than one address. */ +- long stretched; /* Have we stretched on this pass? */ ++ int32_t stretch; /* May be any size, 0 or negative. */ ++ /* Cumulative number of addresses we have */ ++ /* relaxed this pass. */ ++ /* We may have relaxed more than one address. */ ++ int32_t stretched; /* Have we stretched on this pass? */ + /* This is 'cuz stretch may be zero, when, + in fact some piece of code grew, and + another shrank. If a branch instruction + doesn't fit anymore, we need another pass */ + ++#ifndef ARM + const relax_typeS *this_type; + const relax_typeS *start_type; + relax_substateT next_state; + relax_substateT this_state; ++ int32_t aim; ++#endif /* !defined(ARM) */ + +- long growth; +- unsigned long was_address; +- long offset; ++ int32_t growth; ++ uint32_t was_address; ++ int32_t offset; + symbolS *symbolP; +- long target; +- long after; +- long aim; +- unsigned long oldoff, newoff; ++ int32_t target; ++ int32_t after; ++ uint32_t oldoff, newoff; ++ int ret; + ++ ret = 0; + growth = 0; + + /* +@@ -750,6 +1111,9 @@ + */ + address = 0; + for(fragP = frag_root; fragP != NULL; fragP = fragP->fr_next){ ++#ifdef ARM ++ fragP->relax_marker = 0; ++#endif /* ARM */ + fragP->fr_address = address; + address += fragP->fr_fix; + switch(fragP->fr_type){ +@@ -767,12 +1131,12 @@ + * section's alignment. + */ + if(fragP->fr_subtype != 0){ +- if(offset > (long)fragP->fr_subtype){ ++ if(offset > (int32_t)fragP->fr_subtype){ + offset = 0; + } + else{ + if(frchain_now->frch_section.align < +- (unsigned long)fragP->fr_offset) ++ (uint32_t)fragP->fr_offset) + frchain_now->frch_section.align = fragP->fr_offset; + } + } +@@ -789,6 +1153,16 @@ + address += md_estimate_size_before_relax(fragP, nsect); + break; + ++ case rs_dwarf2dbg: ++ address += dwarf2dbg_estimate_size_before_relax(fragP); ++ break; ++ ++ case rs_leb128: ++ /* Initial guess is always 1; doing otherwise can result in ++ stable solutions that are larger than the minimum. */ ++ address += fragP->fr_offset = 1; ++ break; ++ + default: + BAD_CASE(fragP->fr_type); + break; +@@ -806,6 +1180,9 @@ + stretch = 0; + stretched = 0; + for(fragP = frag_root; fragP != NULL; fragP = fragP->fr_next){ ++#ifdef ARM ++ fragP->relax_marker ^= 1; ++#endif /* ARM */ + was_address = fragP->fr_address; + fragP->fr_address += stretch; + address = fragP->fr_address; +@@ -855,6 +1232,9 @@ + break; + + case rs_machine_dependent: ++#ifdef ARM ++ growth = arm_relax_frag(nsect, fragP, stretch); ++#else /* !defined(ARM) */ + this_state = fragP->fr_subtype; + this_type = md_relax_table + this_state; + start_type = this_type; +@@ -906,6 +1286,45 @@ + } + if((growth = this_type->rlx_length -start_type->rlx_length)) + fragP->fr_subtype = this_state; ++#endif /* !defined(ARM) */ ++ break; ++ case rs_dwarf2dbg: ++ growth = dwarf2dbg_relax_frag(fragP); ++ break; ++ ++ case rs_leb128: ++ { ++ valueT value; ++ offsetT size; ++#ifdef OLD ++ value = resolve_symbol_value (fragP->fr_symbol); ++#else ++ expressionS *expression; ++ ++ if(fragP->fr_symbol->expression != NULL){ ++ expression = ++ (expressionS *)fragP->fr_symbol->expression; ++ value = 0; ++ if(expression->X_add_symbol != NULL) ++ value += ++ (expression->X_add_symbol->sy_nlist.n_value + ++ expression->X_add_symbol->sy_frag->fr_address); ++ if(expression->X_subtract_symbol != NULL) ++ value -= ++ (expression->X_subtract_symbol->sy_nlist.n_value + ++ expression->X_subtract_symbol-> ++ sy_frag->fr_address); ++ value += expression->X_add_number; ++ } ++ else{ ++ value = fragP->fr_symbol->sy_nlist.n_value + ++ fragP->fr_address; ++ } ++#endif ++ size = sizeof_leb128 (value, fragP->fr_subtype); ++ growth = size - fragP->fr_offset; ++ fragP->fr_offset = size; ++ } + break; + + default: +@@ -924,6 +1343,14 @@ + * are correct, relative to their own section. We have made all the + * fixS for this section that will be made. + */ ++ ++ for(fragP = frag_root; fragP != NULL; fragP = fragP->fr_next){ ++ if(fragP->last_fr_address != fragP->fr_address){ ++ fragP->last_fr_address = fragP->fr_address; ++ ret = 1; ++ } ++ } ++ return(ret); + } + + /* +@@ -934,7 +1361,7 @@ + relax_addressT /* How many addresses does the .align take? */ + relax_align( + relax_addressT address, /* Address now. */ +-long alignment) /* Alignment (binary). */ ++uint32_t alignment) /* Alignment (binary). */ + { + relax_addressT mask; + relax_addressT new_address; +@@ -944,6 +1371,7 @@ + return(new_address - address); + } + ++#ifndef ARM + /* + * is_down_range() is used in relax_section() to determine it one fragment is + * after another to know if it will also be moved if the first is moved. +@@ -961,3 +1389,4 @@ + } + return(0); + } ++#endif /* !defined(ARM) */ +Index: odcctools-9.2-ld/as/layout.h +=================================================================== +--- odcctools-9.2-ld.orig/as/layout.h 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/as/layout.h 2013-09-03 21:08:01.901209515 +0000 +@@ -1,2 +1,4 @@ ++extern void add_last_frags_to_sections( ++ void); + extern void layout_addresses( + void); +Index: odcctools-9.2-ld/as/messages.c +=================================================================== +--- odcctools-9.2-ld.orig/as/messages.c 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/as/messages.c 2013-09-03 21:08:01.901209515 +0000 +@@ -243,6 +243,32 @@ + } + + /* ++ * Like as_warn_where but the file name and optional line number and column ++ * are passed in. ++ */ ++void ++as_warn_where_with_column (char *file, unsigned int line, unsigned int column, const char *format, ...) ++{ ++ va_list args; ++ ++ if (!flagseen['W']) ++ { ++ print_architecture_banner(); ++ fprintf(stderr, "%s:", file); ++ if (line) ++ { ++ fprintf(stderr, "%u:", line); ++ if (column) ++ fprintf(stderr, "%u:", column); ++ } ++ va_start (args, format); ++ vfprintf(stderr, format, args); ++ fprintf(stderr, "\n"); ++ va_end (args); ++ } ++} ++ ++/* + * a s _ b a d ( ) + * + * Send to stderr a string as a warning, * and locate warning in input file(s). +Index: odcctools-9.2-ld/as/messages.h +=================================================================== +--- odcctools-9.2-ld.orig/as/messages.h 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/as/messages.h 2013-09-03 21:08:01.901209515 +0000 +@@ -21,6 +21,13 @@ + const char *format, + ...) __attribute__ ((format (printf, 3, 4))); + ++extern void as_warn_where_with_column( ++ char *file, ++ unsigned int line, ++ unsigned int column, ++ const char *format, ++ ...) __attribute__ ((format (printf, 4, 5))); ++ + extern void as_bad( + const char *format, + ...) __attribute__ ((format (printf, 1, 2))); +Index: odcctools-9.2-ld/include/mach-o/reloc.h +=================================================================== +--- odcctools-9.2-ld.orig/include/mach-o/reloc.h 2013-09-03 21:08:00.933209537 +0000 ++++ odcctools-9.2-ld/include/mach-o/reloc.h 2013-09-03 21:08:01.901209515 +0000 +@@ -196,7 +196,8 @@ + GENERIC_RELOC_PAIR, /* Only follows a GENERIC_RELOC_SECTDIFF */ + GENERIC_RELOC_SECTDIFF, + GENERIC_RELOC_PB_LA_PTR, /* prebound lazy pointer */ +- GENERIC_RELOC_LOCAL_SECTDIFF ++ GENERIC_RELOC_LOCAL_SECTDIFF, ++ GENERIC_RELOC_TLV /* thread local variables */ + }; + + #endif /* _MACHO_RELOC_H_ */ |