aboutsummaryrefslogtreecommitdiffstats
path: root/recipes-devtools/odcctools/files/cctools-287.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-devtools/odcctools/files/cctools-287.patch')
-rw-r--r--recipes-devtools/odcctools/files/cctools-287.patch13095
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 (&notes, 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(&notes, 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(&notes, c);
++ (void)(obstack_1grow(&notes, c));
+ len++;
+ }
++ /*
++ * This next line is so demand_copy_C_string will return a null
++ * termanated string.
++ */
++ (void)(obstack_1grow(&notes, '\0'));
++ retval = obstack_finish(&notes);
+ }
+ else{
+- while (is_identifier_char(*input_line_pointer)) {
+- obstack_1grow(&notes, *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(&notes, '\0');
+ *lenP = len;
+- retval = obstack_finish(&notes);
+ 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 (&macros, c);
+- obstack_1grow(&macros, '\0');
++ (void)(obstack_1grow (&macros, c));
++ (void)(obstack_1grow(&macros, '\0'));
+ --input_line_pointer;
+ macro_name = obstack_finish(&macros);
+- 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(&macros, '\0');
+-
+- macro_info->contents = obstack_finish(&macros);
+-
+- errorString = hash_insert(ma_hash, macro_name, macro_info);
++ (void)(obstack_1grow(&macros, '\0'));
++ errorString = hash_insert(ma_hash, macro_name,
++ obstack_finish(&macros));
+ 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(&macros, c);
++ (void)(obstack_1grow(&macros, 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(&macros, c);
+- }while(1);
+- obstack_1grow(&macros, '\0');
+- arguments[index] = obstack_finish(&macros);
+- 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(&macros, c));
++ }while(1);
++ (void)(obstack_1grow(&macros, '\0'));
++ arguments[index] = obstack_finish(&macros);
++ 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(&macros, '\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(&macros, 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 (&macros, c);
+- }
+- macro_contents = last_input_line_pointer;
+- continue;
+- }
+- else if (*macro_contents == 'n'){
+- macro_contents++ ;
+- obstack_1grow(&macros, nargs + '0');
+- continue;
+- }
+- }
+- obstack_1grow (&macros, c);
+- }
+-
+- obstack_1grow (&macros, '\n');
+- obstack_1grow (&macros, '\0');
++ (void)(obstack_1grow(&macros, '\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 (&macros, c));
++ }
++ macro_contents = last_input_line_pointer;
++ continue;
++ }
++ else if (*macro_contents == 'n'){
++ macro_contents++ ;
++ (void)(obstack_1grow(&macros, nargs + '0'));
++ continue;
++ }
++ }
++ (void)(obstack_1grow (&macros, c));
++ }
++ (void)(obstack_1grow (&macros, '\n'));
++ (void)(obstack_1grow (&macros, '\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 (&macros, buffer);
+-
+- if (!(info->new_style)) {
+- for(index = 9; index >= 0; index --)
+- if(arguments[index])
+- obstack_free(&macros, arguments[index]);
+- }
+-
++ for(index = 9; index >= 0; index --)
++ if(arguments[index])
++ obstack_free(&macros, 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(&macros, the_char);
++ (void)(obstack_1grow(&macros, the_char));
+ }while(the_char);
+ char_pointer = obstack_finish (&macros);
+ if(!(*char_pointer))
+ break;
+ do{
+ the_char = getc_unlocked(dump_fp);
+- obstack_1grow(&macros, the_char);
++ (void)(obstack_1grow(&macros, the_char));
+ }while(the_char);
+ if(hash_insert(ma_hash, char_pointer,
+ obstack_finish(&macros)))
+@@ -4861,7 +4690,7 @@
+ do{
+ do{
+ the_char = getc_unlocked(dump_fp);
+- obstack_1grow(&macros, the_char);
++ (void)(obstack_1grow(&macros, the_char));
+ }while(the_char);
+ char_pointer = obstack_base(&macros);
+ obstack_next_free(&macros) = 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_ */