uClibc-26042011-git.patch 79 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506
  1. diff -Nur uClibc-0.9.32-rc3/extra/Configs/Config.in uClibc/extra/Configs/Config.in
  2. --- uClibc-0.9.32-rc3/extra/Configs/Config.in 2011-03-16 20:11:13.000000000 +0100
  3. +++ uClibc/extra/Configs/Config.in 2011-04-26 16:18:21.707661578 +0200
  4. @@ -1898,6 +1898,18 @@
  5. This interface is rarely used, and adds around 4.5k. Unless you have
  6. a pressing need for ftw(), you should probably answer N.
  7. +config UCLIBC_HAS_FTS
  8. + bool "Support the fts() interface (bsd-compat)"
  9. + default n
  10. + help
  11. + The fts functions are provided for traversing UNIX file hierarchies.
  12. +
  13. + This interface is currently used by the elfutils and adds
  14. + around 7.5k.
  15. + You should port your application to use the POSIX nftw()
  16. + interface.
  17. +
  18. + Unless you need to build/use elfutils, you should prolly answer N.
  19. config UCLIBC_HAS_GLOB
  20. bool "Support the glob() interface"
  21. @@ -2322,7 +2334,7 @@
  22. config UCLIBC_HAS_BACKTRACE
  23. bool "Add support for application self-debugging"
  24. - depends on HAVE_SHARED && TARGET_sh
  25. + depends on HAVE_SHARED
  26. default n
  27. help
  28. Answer Y here to compile support for application self-debugging, by adding
  29. diff -Nur uClibc-0.9.32-rc3/include/fts.h uClibc/include/fts.h
  30. --- uClibc-0.9.32-rc3/include/fts.h 1970-01-01 01:00:00.000000000 +0100
  31. +++ uClibc/include/fts.h 2011-04-26 16:18:21.727663221 +0200
  32. @@ -0,0 +1,131 @@
  33. +/*
  34. + * Copyright (c) 1989, 1993
  35. + * The Regents of the University of California. All rights reserved.
  36. + *
  37. + * Redistribution and use in source and binary forms, with or without
  38. + * modification, are permitted provided that the following conditions
  39. + * are met:
  40. + * 1. Redistributions of source code must retain the above copyright
  41. + * notice, this list of conditions and the following disclaimer.
  42. + * 2. Redistributions in binary form must reproduce the above copyright
  43. + * notice, this list of conditions and the following disclaimer in the
  44. + * documentation and/or other materials provided with the distribution.
  45. + * 4. Neither the name of the University nor the names of its contributors
  46. + * may be used to endorse or promote products derived from this software
  47. + * without specific prior written permission.
  48. + *
  49. + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  50. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  51. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  52. + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  53. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  54. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  55. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  56. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  57. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  58. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  59. + * SUCH DAMAGE.
  60. + *
  61. + * @(#)fts.h 8.3 (Berkeley) 8/14/94
  62. + */
  63. +
  64. +#ifndef _FTS_H
  65. +#define _FTS_H 1
  66. +
  67. +#include <features.h>
  68. +#include <sys/types.h>
  69. +
  70. +/* The fts interface is incompatible with the LFS interface which
  71. + transparently uses the 64-bit file access functions. */
  72. +#ifdef __USE_FILE_OFFSET64
  73. +# error "<fts.h> cannot be used with -D_FILE_OFFSET_BITS==64"
  74. +#endif
  75. +
  76. +
  77. +typedef struct {
  78. + struct _ftsent *fts_cur; /* current node */
  79. + struct _ftsent *fts_child; /* linked list of children */
  80. + struct _ftsent **fts_array; /* sort array */
  81. + dev_t fts_dev; /* starting device # */
  82. + char *fts_path; /* path for this descent */
  83. + int fts_rfd; /* fd for root */
  84. + int fts_pathlen; /* sizeof(path) */
  85. + int fts_nitems; /* elements in the sort array */
  86. + int (*fts_compar) (const void *, const void *); /* compare fn */
  87. +
  88. +#define FTS_COMFOLLOW 0x0001 /* follow command line symlinks */
  89. +#define FTS_LOGICAL 0x0002 /* logical walk */
  90. +#define FTS_NOCHDIR 0x0004 /* don't change directories */
  91. +#define FTS_NOSTAT 0x0008 /* don't get stat info */
  92. +#define FTS_PHYSICAL 0x0010 /* physical walk */
  93. +#define FTS_SEEDOT 0x0020 /* return dot and dot-dot */
  94. +#define FTS_XDEV 0x0040 /* don't cross devices */
  95. +#define FTS_WHITEOUT 0x0080 /* return whiteout information */
  96. +#define FTS_OPTIONMASK 0x00ff /* valid user option mask */
  97. +
  98. +#define FTS_NAMEONLY 0x0100 /* (private) child names only */
  99. +#define FTS_STOP 0x0200 /* (private) unrecoverable error */
  100. + int fts_options; /* fts_open options, global flags */
  101. +} FTS;
  102. +
  103. +typedef struct _ftsent {
  104. + struct _ftsent *fts_cycle; /* cycle node */
  105. + struct _ftsent *fts_parent; /* parent directory */
  106. + struct _ftsent *fts_link; /* next file in directory */
  107. + long fts_number; /* local numeric value */
  108. + void *fts_pointer; /* local address value */
  109. + char *fts_accpath; /* access path */
  110. + char *fts_path; /* root path */
  111. + int fts_errno; /* errno for this node */
  112. + int fts_symfd; /* fd for symlink */
  113. + u_short fts_pathlen; /* strlen(fts_path) */
  114. + u_short fts_namelen; /* strlen(fts_name) */
  115. +
  116. + ino_t fts_ino; /* inode */
  117. + dev_t fts_dev; /* device */
  118. + nlink_t fts_nlink; /* link count */
  119. +
  120. +#define FTS_ROOTPARENTLEVEL -1
  121. +#define FTS_ROOTLEVEL 0
  122. + short fts_level; /* depth (-1 to N) */
  123. +
  124. +#define FTS_D 1 /* preorder directory */
  125. +#define FTS_DC 2 /* directory that causes cycles */
  126. +#define FTS_DEFAULT 3 /* none of the above */
  127. +#define FTS_DNR 4 /* unreadable directory */
  128. +#define FTS_DOT 5 /* dot or dot-dot */
  129. +#define FTS_DP 6 /* postorder directory */
  130. +#define FTS_ERR 7 /* error; errno is set */
  131. +#define FTS_F 8 /* regular file */
  132. +#define FTS_INIT 9 /* initialized only */
  133. +#define FTS_NS 10 /* stat(2) failed */
  134. +#define FTS_NSOK 11 /* no stat(2) requested */
  135. +#define FTS_SL 12 /* symbolic link */
  136. +#define FTS_SLNONE 13 /* symbolic link without target */
  137. +#define FTS_W 14 /* whiteout object */
  138. + u_short fts_info; /* user flags for FTSENT structure */
  139. +
  140. +#define FTS_DONTCHDIR 0x01 /* don't chdir .. to the parent */
  141. +#define FTS_SYMFOLLOW 0x02 /* followed a symlink to get here */
  142. + u_short fts_flags; /* private flags for FTSENT structure */
  143. +
  144. +#define FTS_AGAIN 1 /* read node again */
  145. +#define FTS_FOLLOW 2 /* follow symbolic link */
  146. +#define FTS_NOINSTR 3 /* no instructions */
  147. +#define FTS_SKIP 4 /* discard node */
  148. + u_short fts_instr; /* fts_set() instructions */
  149. +
  150. + struct stat *fts_statp; /* stat(2) information */
  151. + char fts_name[1]; /* file name */
  152. +} FTSENT;
  153. +
  154. +__BEGIN_DECLS
  155. +FTSENT *fts_children (FTS *, int);
  156. +int fts_close (FTS *);
  157. +FTS *fts_open (char * const *, int,
  158. + int (*)(const FTSENT **, const FTSENT **));
  159. +FTSENT *fts_read (FTS *);
  160. +int fts_set (FTS *, FTSENT *, int) __THROW;
  161. +__END_DECLS
  162. +
  163. +#endif /* fts.h */
  164. diff -Nur uClibc-0.9.32-rc3/ldso/include/dl-elf.h uClibc/ldso/include/dl-elf.h
  165. --- uClibc-0.9.32-rc3/ldso/include/dl-elf.h 2011-03-16 20:11:13.000000000 +0100
  166. +++ uClibc/ldso/include/dl-elf.h 2011-04-26 16:18:21.747664948 +0200
  167. @@ -184,7 +184,7 @@
  168. ADJUST_DYN_INFO(DT_DSBT_BASE_IDX, load_off);
  169. /* Initialize loadmap dsbt info. */
  170. - load_off.map->dsbt_table = dynamic_info[DT_DSBT_BASE_IDX];
  171. + load_off.map->dsbt_table = (void *)dynamic_info[DT_DSBT_BASE_IDX];
  172. load_off.map->dsbt_size = dynamic_info[DT_DSBT_SIZE_IDX];
  173. load_off.map->dsbt_index = dynamic_info[DT_DSBT_INDEX_IDX];
  174. #endif
  175. diff -Nur uClibc-0.9.32-rc3/ldso/include/ldso.h uClibc/ldso/include/ldso.h
  176. --- uClibc-0.9.32-rc3/ldso/include/ldso.h 2011-03-16 20:11:13.000000000 +0100
  177. +++ uClibc/ldso/include/ldso.h 2011-04-26 16:18:21.747664948 +0200
  178. @@ -34,6 +34,8 @@
  179. #include <sys/types.h>
  180. /* Pull in the arch specific page size */
  181. #include <bits/uClibc_page.h>
  182. +/* Pull in the MIN macro */
  183. +#include <sys/param.h>
  184. /* Pull in the ldso syscalls and string functions */
  185. #ifndef __ARCH_HAS_NO_SHARED__
  186. #include <dl-syscall.h>
  187. diff -Nur uClibc-0.9.32-rc3/ldso/ldso/bfin/dl-inlines.h uClibc/ldso/ldso/bfin/dl-inlines.h
  188. --- uClibc-0.9.32-rc3/ldso/ldso/bfin/dl-inlines.h 2011-03-16 20:11:13.000000000 +0100
  189. +++ uClibc/ldso/ldso/bfin/dl-inlines.h 2011-04-26 16:18:21.747664948 +0200
  190. @@ -88,14 +88,39 @@
  191. segdata->p_memsz = phdr->p_memsz;
  192. #if defined (__SUPPORT_LD_DEBUG__)
  193. - {
  194. - extern char *_dl_debug;
  195. - extern int _dl_debug_file;
  196. - if (_dl_debug)
  197. - _dl_dprintf(_dl_debug_file, "%i: mapped %x at %x, size %x\n",
  198. - loadaddr.map->nsegs-1,
  199. - segdata->p_vaddr, segdata->addr, segdata->p_memsz);
  200. - }
  201. + if (_dl_debug)
  202. + _dl_dprintf(_dl_debug_file, "%i: mapped %x at %x, size %x\n",
  203. + loadaddr.map->nsegs-1,
  204. + segdata->p_vaddr, segdata->addr, segdata->p_memsz);
  205. +#endif
  206. +}
  207. +
  208. +/* Replace an existing entry in the load map. */
  209. +static __always_inline void
  210. +__dl_update_loadaddr_hdr (struct elf32_fdpic_loadaddr loadaddr, void *addr,
  211. + Elf32_Phdr *phdr)
  212. +{
  213. + struct elf32_fdpic_loadseg *segdata;
  214. + void *oldaddr;
  215. + int i;
  216. +
  217. + for (i = 0; i < loadaddr.map->nsegs; i++)
  218. + if (loadaddr.map->segs[i].p_vaddr == phdr->p_vaddr
  219. + && loadaddr.map->segs[i].p_memsz == phdr->p_memsz)
  220. + break;
  221. + if (i == loadaddr.map->nsegs)
  222. + _dl_exit (-1);
  223. +
  224. + segdata = loadaddr.map->segs + i;
  225. + oldaddr = (void *)segdata->addr;
  226. + _dl_munmap (oldaddr, segdata->p_memsz);
  227. + segdata->addr = (Elf32_Addr) addr;
  228. +
  229. +#if defined (__SUPPORT_LD_DEBUG__)
  230. + if (_dl_debug)
  231. + _dl_dprintf(_dl_debug_file, "%i: changed mapping %x at %x (old %x), size %x\n",
  232. + loadaddr.map->nsegs-1,
  233. + segdata->p_vaddr, segdata->addr, oldaddr, segdata->p_memsz);
  234. #endif
  235. }
  236. diff -Nur uClibc-0.9.32-rc3/ldso/ldso/bfin/dl-sysdep.h uClibc/ldso/ldso/bfin/dl-sysdep.h
  237. --- uClibc-0.9.32-rc3/ldso/ldso/bfin/dl-sysdep.h 2011-03-16 20:11:13.000000000 +0100
  238. +++ uClibc/ldso/ldso/bfin/dl-sysdep.h 2011-04-26 16:18:21.747664948 +0200
  239. @@ -120,6 +120,8 @@
  240. #define DL_INIT_LOADADDR_HDR(LOADADDR, ADDR, PHDR) \
  241. (__dl_init_loadaddr_hdr ((LOADADDR), (ADDR), (PHDR), \
  242. dl_init_loadaddr_load_count))
  243. +#define DL_UPDATE_LOADADDR_HDR(LOADADDR, ADDR, PHDR) \
  244. + (__dl_update_loadaddr_hdr ((LOADADDR), (ADDR), (PHDR)))
  245. #define DL_LOADADDR_UNMAP(LOADADDR, LEN) \
  246. (__dl_loadaddr_unmap ((LOADADDR), (NULL)))
  247. #define DL_LIB_UNMAP(LIB, LEN) \
  248. diff -Nur uClibc-0.9.32-rc3/ldso/ldso/c6x/dl-inlines.h uClibc/ldso/ldso/c6x/dl-inlines.h
  249. --- uClibc-0.9.32-rc3/ldso/ldso/c6x/dl-inlines.h 2011-03-16 20:11:13.000000000 +0100
  250. +++ uClibc/ldso/ldso/c6x/dl-inlines.h 2011-04-26 16:18:21.747664948 +0200
  251. @@ -74,6 +74,35 @@
  252. #endif
  253. }
  254. +/* Replace an existing entry in the load map. */
  255. +static __always_inline void
  256. +__dl_update_loadaddr_hdr (struct elf32_dsbt_loadaddr loadaddr, void *addr,
  257. + Elf32_Phdr *phdr)
  258. +{
  259. + struct elf32_dsbt_loadseg *segdata;
  260. + void *oldaddr;
  261. + int i;
  262. +
  263. + for (i = 0; i < loadaddr.map->nsegs; i++)
  264. + if (loadaddr.map->segs[i].p_vaddr == phdr->p_vaddr
  265. + && loadaddr.map->segs[i].p_memsz == phdr->p_memsz)
  266. + break;
  267. + if (i == loadaddr.map->nsegs)
  268. + _dl_exit (-1);
  269. +
  270. + segdata = loadaddr.map->segs + i;
  271. + oldaddr = (void *)segdata->addr;
  272. + _dl_munmap (oldaddr, segdata->p_memsz);
  273. + segdata->addr = (Elf32_Addr) addr;
  274. +
  275. +#if defined (__SUPPORT_LD_DEBUG__)
  276. + if (_dl_debug)
  277. + _dl_dprintf(_dl_debug_file, "%i: changed mapping %x at %x (old %x), size %x\n",
  278. + loadaddr.map->nsegs-1,
  279. + segdata->p_vaddr, segdata->addr, oldaddr, segdata->p_memsz);
  280. +#endif
  281. +}
  282. +
  283. static __always_inline void
  284. __dl_loadaddr_unmap (struct elf32_dsbt_loadaddr loadaddr)
  285. {
  286. diff -Nur uClibc-0.9.32-rc3/ldso/ldso/c6x/dl-sysdep.h uClibc/ldso/ldso/c6x/dl-sysdep.h
  287. --- uClibc-0.9.32-rc3/ldso/ldso/c6x/dl-sysdep.h 2011-03-16 20:11:13.000000000 +0100
  288. +++ uClibc/ldso/ldso/c6x/dl-sysdep.h 2011-04-26 16:18:21.747664948 +0200
  289. @@ -104,6 +104,9 @@
  290. (__dl_init_loadaddr_hdr ((LOADADDR), (ADDR), (PHDR), \
  291. dl_init_loadaddr_load_count))
  292. +#define DL_UPDATE_LOADADDR_HDR(LOADADDR, ADDR, PHDR) \
  293. + (__dl_update_loadaddr_hdr ((LOADADDR), (ADDR), (PHDR)))
  294. +
  295. #define DL_LOADADDR_UNMAP(LOADADDR, LEN) \
  296. (__dl_loadaddr_unmap ((LOADADDR)))
  297. diff -Nur uClibc-0.9.32-rc3/ldso/ldso/c6x/elfinterp.c uClibc/ldso/ldso/c6x/elfinterp.c
  298. --- uClibc-0.9.32-rc3/ldso/ldso/c6x/elfinterp.c 2011-03-16 20:11:13.000000000 +0100
  299. +++ uClibc/ldso/ldso/c6x/elfinterp.c 2011-04-26 16:18:21.747664948 +0200
  300. @@ -198,6 +198,10 @@
  301. new_val = sym_val;
  302. *reloc_addr = sym_val;
  303. break;
  304. + case R_C6000_DSBT_INDEX:
  305. + new_val = (old_val & ~0x007fff00) | ((tpnt->loadaddr.map->dsbt_index & 0x7fff) << 8);
  306. + *reloc_addr = new_val;
  307. + break;
  308. case R_C6000_ABS_L16:
  309. new_val = (old_val & ~0x007fff80) | ((sym_val & 0xffff) << 7);
  310. *reloc_addr = new_val;
  311. @@ -224,7 +228,7 @@
  312. (char *)symbol_addr,
  313. symtab[symtab_index].st_size);
  314. }
  315. - break;
  316. + return 0;
  317. default:
  318. return -1; /*call _dl_exit(1) */
  319. }
  320. diff -Nur uClibc-0.9.32-rc3/ldso/ldso/dl-elf.c uClibc/ldso/ldso/dl-elf.c
  321. --- uClibc-0.9.32-rc3/ldso/ldso/dl-elf.c 2011-03-16 20:11:13.000000000 +0100
  322. +++ uClibc/ldso/ldso/dl-elf.c 2011-04-26 16:18:21.747664948 +0200
  323. @@ -314,6 +314,121 @@
  324. return NULL;
  325. }
  326. +/*
  327. + * Make a writeable mapping of a segment, regardless of whether PF_W is
  328. + * set or not.
  329. + */
  330. +static void *
  331. +map_writeable (int infile, ElfW(Phdr) *ppnt, int piclib, int flags,
  332. + unsigned long libaddr)
  333. +{
  334. + int prot_flags = ppnt->p_flags | PF_W;
  335. + char *status, *retval;
  336. + char *tryaddr;
  337. + ssize_t size;
  338. + unsigned long map_size;
  339. + char *cpnt;
  340. + char *piclib2map = NULL;
  341. +
  342. + if (piclib == 2 &&
  343. + /* We might be able to avoid this call if memsz doesn't
  344. + require an additional page, but this would require mmap
  345. + to always return page-aligned addresses and a whole
  346. + number of pages allocated. Unfortunately on uClinux
  347. + may return misaligned addresses and may allocate
  348. + partial pages, so we may end up doing unnecessary mmap
  349. + calls.
  350. +
  351. + This is what we could do if we knew mmap would always
  352. + return aligned pages:
  353. +
  354. + ((ppnt->p_vaddr + ppnt->p_filesz + ADDR_ALIGN) &
  355. + PAGE_ALIGN) < ppnt->p_vaddr + ppnt->p_memsz)
  356. +
  357. + Instead, we have to do this: */
  358. + ppnt->p_filesz < ppnt->p_memsz)
  359. + {
  360. + piclib2map = (char *)
  361. + _dl_mmap(0, (ppnt->p_vaddr & ADDR_ALIGN) + ppnt->p_memsz,
  362. + LXFLAGS(prot_flags), flags | MAP_ANONYMOUS, -1, 0);
  363. + if (_dl_mmap_check_error(piclib2map))
  364. + return 0;
  365. + }
  366. +
  367. + tryaddr = piclib == 2 ? piclib2map
  368. + : ((char*) (piclib ? libaddr : 0) +
  369. + (ppnt->p_vaddr & PAGE_ALIGN));
  370. +
  371. + size = (ppnt->p_vaddr & ADDR_ALIGN) + ppnt->p_filesz;
  372. +
  373. + /* For !MMU, mmap to fixed address will fail.
  374. + So instead of desperately call mmap and fail,
  375. + we set status to MAP_FAILED to save a call
  376. + to mmap (). */
  377. +#ifndef __ARCH_USE_MMU__
  378. + if (piclib2map == 0)
  379. +#endif
  380. + status = (char *) _dl_mmap
  381. + (tryaddr, size, LXFLAGS(prot_flags),
  382. + flags | (piclib2map ? MAP_FIXED : 0),
  383. + infile, ppnt->p_offset & OFFS_ALIGN);
  384. +#ifndef __ARCH_USE_MMU__
  385. + else
  386. + status = MAP_FAILED;
  387. +#endif
  388. +#ifdef _DL_PREAD
  389. + if (_dl_mmap_check_error(status) && piclib2map
  390. + && (_DL_PREAD (infile, tryaddr, size,
  391. + ppnt->p_offset & OFFS_ALIGN) == size))
  392. + status = tryaddr;
  393. +#endif
  394. + if (_dl_mmap_check_error(status) || (tryaddr && tryaddr != status))
  395. + return 0;
  396. +
  397. + if (piclib2map)
  398. + retval = piclib2map;
  399. + else
  400. + retval = status;
  401. +
  402. + /* Now we want to allocate and zero-out any data from the end
  403. + of the region we mapped in from the file (filesz) to the
  404. + end of the loadable segment (memsz). We may need
  405. + additional pages for memsz, that we map in below, and we
  406. + can count on the kernel to zero them out, but we have to
  407. + zero out stuff in the last page that we mapped in from the
  408. + file. However, we can't assume to have actually obtained
  409. + full pages from the kernel, since we didn't ask for them,
  410. + and uClibc may not give us full pages for small
  411. + allocations. So only zero out up to memsz or the end of
  412. + the page, whichever comes first. */
  413. +
  414. + /* CPNT is the beginning of the memsz portion not backed by
  415. + filesz. */
  416. + cpnt = (char *) (status + size);
  417. +
  418. + /* MAP_SIZE is the address of the
  419. + beginning of the next page. */
  420. + map_size = (ppnt->p_vaddr + ppnt->p_filesz
  421. + + ADDR_ALIGN) & PAGE_ALIGN;
  422. +
  423. + _dl_memset (cpnt, 0,
  424. + MIN (map_size
  425. + - (ppnt->p_vaddr
  426. + + ppnt->p_filesz),
  427. + ppnt->p_memsz
  428. + - ppnt->p_filesz));
  429. +
  430. + if (map_size < ppnt->p_vaddr + ppnt->p_memsz && !piclib2map) {
  431. + tryaddr = map_size + (char*)(piclib ? libaddr : 0);
  432. + status = (char *) _dl_mmap(tryaddr,
  433. + ppnt->p_vaddr + ppnt->p_memsz - map_size,
  434. + LXFLAGS(prot_flags),
  435. + flags | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
  436. + if (_dl_mmap_check_error(status) || tryaddr != status)
  437. + return NULL;
  438. + }
  439. + return retval;
  440. +}
  441. /*
  442. * Read one ELF library into memory, mmap it into the correct locations and
  443. @@ -475,6 +590,7 @@
  444. status = (char *) _dl_mmap((char *) (piclib ? 0 : minvma),
  445. maxvma - minvma, PROT_NONE, flags | MAP_ANONYMOUS, -1, 0);
  446. if (_dl_mmap_check_error(status)) {
  447. + cant_map:
  448. _dl_dprintf(2, "%s:%i: can't map '%s'\n", _dl_progname, __LINE__, libname);
  449. _dl_internal_error_number = LD_ERROR_MMAP_FAILED;
  450. _dl_close(infile);
  451. @@ -495,8 +611,11 @@
  452. char *addr;
  453. addr = DL_MAP_SEGMENT (epnt, ppnt, infile, flags);
  454. - if (addr == NULL)
  455. + if (addr == NULL) {
  456. + cant_map1:
  457. + DL_LOADADDR_UNMAP (lib_loadaddr, maxvma - minvma);
  458. goto cant_map;
  459. + }
  460. DL_INIT_LOADADDR_HDR (lib_loadaddr, addr, ppnt);
  461. ppnt++;
  462. @@ -517,141 +636,9 @@
  463. }
  464. if (ppnt->p_flags & PF_W) {
  465. - unsigned long map_size;
  466. - char *cpnt;
  467. - char *piclib2map = 0;
  468. -
  469. - if (piclib == 2 &&
  470. - /* We might be able to avoid this
  471. - call if memsz doesn't require
  472. - an additional page, but this
  473. - would require mmap to always
  474. - return page-aligned addresses
  475. - and a whole number of pages
  476. - allocated. Unfortunately on
  477. - uClinux may return misaligned
  478. - addresses and may allocate
  479. - partial pages, so we may end up
  480. - doing unnecessary mmap calls.
  481. -
  482. - This is what we could do if we
  483. - knew mmap would always return
  484. - aligned pages:
  485. -
  486. - ((ppnt->p_vaddr + ppnt->p_filesz
  487. - + ADDR_ALIGN)
  488. - & PAGE_ALIGN)
  489. - < ppnt->p_vaddr + ppnt->p_memsz)
  490. -
  491. - Instead, we have to do this: */
  492. - ppnt->p_filesz < ppnt->p_memsz)
  493. - {
  494. - piclib2map = (char *)
  495. - _dl_mmap(0, (ppnt->p_vaddr & ADDR_ALIGN)
  496. - + ppnt->p_memsz,
  497. - LXFLAGS(ppnt->p_flags),
  498. - flags | MAP_ANONYMOUS, -1, 0);
  499. - if (_dl_mmap_check_error(piclib2map))
  500. - goto cant_map;
  501. - DL_INIT_LOADADDR_HDR
  502. - (lib_loadaddr, piclib2map
  503. - + (ppnt->p_vaddr & ADDR_ALIGN), ppnt);
  504. - }
  505. -
  506. - tryaddr = piclib == 2 ? piclib2map
  507. - : ((char*) (piclib ? libaddr : 0) +
  508. - (ppnt->p_vaddr & PAGE_ALIGN));
  509. -
  510. - size = (ppnt->p_vaddr & ADDR_ALIGN)
  511. - + ppnt->p_filesz;
  512. -
  513. - /* For !MMU, mmap to fixed address will fail.
  514. - So instead of desperately call mmap and fail,
  515. - we set status to MAP_FAILED to save a call
  516. - to mmap (). */
  517. -#ifndef __ARCH_USE_MMU__
  518. - if (piclib2map == 0)
  519. -#endif
  520. - status = (char *) _dl_mmap
  521. - (tryaddr, size, LXFLAGS(ppnt->p_flags),
  522. - flags | (piclib2map ? MAP_FIXED : 0),
  523. - infile, ppnt->p_offset & OFFS_ALIGN);
  524. -#ifndef __ARCH_USE_MMU__
  525. - else
  526. - status = MAP_FAILED;
  527. -#endif
  528. -#ifdef _DL_PREAD
  529. - if (_dl_mmap_check_error(status) && piclib2map
  530. - && (_DL_PREAD (infile, tryaddr, size,
  531. - ppnt->p_offset & OFFS_ALIGN)
  532. - == size))
  533. - status = tryaddr;
  534. -#endif
  535. - if (_dl_mmap_check_error(status)
  536. - || (tryaddr && tryaddr != status)) {
  537. - cant_map:
  538. - _dl_dprintf(2, "%s:%i: can't map '%s'\n",
  539. - _dl_progname, __LINE__, libname);
  540. - _dl_internal_error_number = LD_ERROR_MMAP_FAILED;
  541. - DL_LOADADDR_UNMAP (lib_loadaddr, maxvma - minvma);
  542. - _dl_close(infile);
  543. - _dl_munmap(header, _dl_pagesize);
  544. - return NULL;
  545. - }
  546. -
  547. - if (! piclib2map) {
  548. - DL_INIT_LOADADDR_HDR
  549. - (lib_loadaddr, status
  550. - + (ppnt->p_vaddr & ADDR_ALIGN), ppnt);
  551. - }
  552. - /* Now we want to allocate and
  553. - zero-out any data from the end of
  554. - the region we mapped in from the
  555. - file (filesz) to the end of the
  556. - loadable segment (memsz). We may
  557. - need additional pages for memsz,
  558. - that we map in below, and we can
  559. - count on the kernel to zero them
  560. - out, but we have to zero out stuff
  561. - in the last page that we mapped in
  562. - from the file. However, we can't
  563. - assume to have actually obtained
  564. - full pages from the kernel, since
  565. - we didn't ask for them, and uClibc
  566. - may not give us full pages for
  567. - small allocations. So only zero
  568. - out up to memsz or the end of the
  569. - page, whichever comes first. */
  570. -
  571. - /* CPNT is the beginning of the memsz
  572. - portion not backed by filesz. */
  573. - cpnt = (char *) (status + size);
  574. -
  575. - /* MAP_SIZE is the address of the
  576. - beginning of the next page. */
  577. - map_size = (ppnt->p_vaddr + ppnt->p_filesz
  578. - + ADDR_ALIGN) & PAGE_ALIGN;
  579. -
  580. -#ifndef MIN
  581. -# define MIN(a,b) ((a) < (b) ? (a) : (b))
  582. -#endif
  583. - _dl_memset (cpnt, 0,
  584. - MIN (map_size
  585. - - (ppnt->p_vaddr
  586. - + ppnt->p_filesz),
  587. - ppnt->p_memsz
  588. - - ppnt->p_filesz));
  589. -
  590. - if (map_size < ppnt->p_vaddr + ppnt->p_memsz
  591. - && !piclib2map) {
  592. - tryaddr = map_size + (char*)(piclib ? libaddr : 0);
  593. - status = (char *) _dl_mmap(tryaddr,
  594. - ppnt->p_vaddr + ppnt->p_memsz - map_size,
  595. - LXFLAGS(ppnt->p_flags), flags | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
  596. - if (_dl_mmap_check_error(status)
  597. - || tryaddr != status)
  598. - goto cant_map;
  599. - }
  600. + status = map_writeable (infile, ppnt, piclib, flags, libaddr);
  601. + if (status == NULL)
  602. + goto cant_map1;
  603. } else {
  604. tryaddr = (piclib == 2 ? 0
  605. : (char *) (ppnt->p_vaddr & PAGE_ALIGN)
  606. @@ -664,11 +651,11 @@
  607. infile, ppnt->p_offset & OFFS_ALIGN);
  608. if (_dl_mmap_check_error(status)
  609. || (tryaddr && tryaddr != status))
  610. - goto cant_map;
  611. - DL_INIT_LOADADDR_HDR
  612. - (lib_loadaddr, status
  613. - + (ppnt->p_vaddr & ADDR_ALIGN), ppnt);
  614. + goto cant_map1;
  615. }
  616. + DL_INIT_LOADADDR_HDR(lib_loadaddr,
  617. + status + (ppnt->p_vaddr & ADDR_ALIGN),
  618. + ppnt);
  619. /* if (libaddr == 0 && piclib) {
  620. libaddr = (unsigned long) status;
  621. @@ -677,7 +664,6 @@
  622. }
  623. ppnt++;
  624. }
  625. - _dl_close(infile);
  626. /* For a non-PIC library, the addresses are all absolute */
  627. if (piclib) {
  628. @@ -696,6 +682,7 @@
  629. _dl_dprintf(2, "%s: '%s' is missing a dynamic section\n",
  630. _dl_progname, libname);
  631. _dl_munmap(header, _dl_pagesize);
  632. + _dl_close(infile);
  633. return NULL;
  634. }
  635. @@ -711,10 +698,23 @@
  636. ppnt = (ElfW(Phdr) *)(intptr_t) & header[epnt->e_phoff];
  637. for (i = 0; i < epnt->e_phnum; i++, ppnt++) {
  638. if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W)) {
  639. +#ifdef __ARCH_USE_MMU__
  640. _dl_mprotect((void *) ((piclib ? libaddr : 0) +
  641. (ppnt->p_vaddr & PAGE_ALIGN)),
  642. (ppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) ppnt->p_filesz,
  643. PROT_READ | PROT_WRITE | PROT_EXEC);
  644. +#else
  645. + void *new_addr;
  646. + new_addr = map_writeable (infile, ppnt, piclib, flags, libaddr);
  647. + if (!new_addr) {
  648. + _dl_dprintf(_dl_debug_file, "Can't modify %s's text section.",
  649. + libname);
  650. + _dl_exit(1);
  651. + }
  652. + DL_UPDATE_LOADADDR_HDR(lib_loadaddr,
  653. + new_addr + (ppnt->p_vaddr & ADDR_ALIGN),
  654. + ppnt);
  655. +#endif
  656. }
  657. }
  658. #else
  659. @@ -725,6 +725,8 @@
  660. #endif
  661. }
  662. + _dl_close(infile);
  663. +
  664. tpnt = _dl_add_elf_hash_table(libname, lib_loadaddr, dynamic_info,
  665. dynamic_addr, 0);
  666. tpnt->relro_addr = relro_addr;
  667. @@ -809,20 +811,44 @@
  668. #ifdef __DSBT__
  669. /* Handle DSBT initialization */
  670. {
  671. - struct elf_resolve *t, *ref = NULL;
  672. + struct elf_resolve *t, *ref;
  673. int idx = tpnt->loadaddr.map->dsbt_index;
  674. unsigned *dsbt = tpnt->loadaddr.map->dsbt_table;
  675. if (idx == 0) {
  676. - /* This DSO has not been assigned an index */
  677. - _dl_dprintf(2, "%s: '%s' is missing a dsbt index assignment!\n",
  678. - _dl_progname, libname);
  679. - _dl_exit(1);
  680. + if (!dynamic_info[DT_TEXTREL]) {
  681. + /* This DSO has not been assigned an index. */
  682. + _dl_dprintf(2, "%s: '%s' is missing a dsbt index assignment!\n",
  683. + _dl_progname, libname);
  684. + _dl_exit(1);
  685. + }
  686. + /* Find a dsbt table from another module. */
  687. + ref = NULL;
  688. + for (t = _dl_loaded_modules; t; t = t->next) {
  689. + if (ref == NULL && t != tpnt) {
  690. + ref = t;
  691. + break;
  692. + }
  693. + }
  694. + idx = tpnt->loadaddr.map->dsbt_size;
  695. + while (idx-- > 0)
  696. + if (!ref || ref->loadaddr.map->dsbt_table[idx] == NULL)
  697. + break;
  698. + if (idx <= 0) {
  699. + _dl_dprintf(2, "%s: '%s' caused DSBT table overflow!\n",
  700. + _dl_progname, libname);
  701. + _dl_exit(1);
  702. + }
  703. + _dl_if_debug_dprint("\n\tfile='%s'; assigned index %d\n",
  704. + libname, idx);
  705. + tpnt->loadaddr.map->dsbt_index = idx;
  706. +
  707. }
  708. /*
  709. * Setup dsbt slot for this module in dsbt of all modules.
  710. */
  711. + ref = NULL;
  712. for (t = _dl_loaded_modules; t; t = t->next) {
  713. /* find a dsbt table from another module */
  714. if (ref == NULL && t != tpnt) {
  715. diff -Nur uClibc-0.9.32-rc3/ldso/ldso/dl-startup.c uClibc/ldso/ldso/dl-startup.c
  716. --- uClibc-0.9.32-rc3/ldso/ldso/dl-startup.c 2011-03-16 20:11:13.000000000 +0100
  717. +++ uClibc/ldso/ldso/dl-startup.c 2011-04-26 16:18:21.747664948 +0200
  718. @@ -32,8 +32,8 @@
  719. /*
  720. * The main trick with this program is that initially, we ourselves are not
  721. - * dynamicly linked. This means that we cannot access any global variables or
  722. - * call any functions. No globals initially, since the Global Offset Table
  723. + * dynamically linked. This means that we cannot access any global variables
  724. + * or call any functions. No globals initially, since the Global Offset Table
  725. * (GOT) is initialized by the linker assuming a virtual address of 0, and no
  726. * function calls initially since the Procedure Linkage Table (PLT) is not yet
  727. * initialized.
  728. @@ -55,12 +55,12 @@
  729. *
  730. * Fortunately, the linker itself leaves a few clues lying around, and when the
  731. * kernel starts the image, there are a few further clues. First of all, there
  732. - * is Auxiliary Vector Table information sitting on which is provided to us by
  733. - * the kernel, and which includes information about the load address that the
  734. - * program interpreter was loaded at, the number of sections, the address the
  735. - * application was loaded at and so forth. Here this information is stored in
  736. - * the array auxvt. For details see linux/fs/binfmt_elf.c where it calls
  737. - * NEW_AUX_ENT() a bunch of time....
  738. + * is Auxiliary Vector Table information sitting on the stack which is provided
  739. + * to us by the kernel, and which includes information about the address
  740. + * that the program interpreter was loaded at, the number of sections, the
  741. + * address the application was loaded at, and so forth. Here this information
  742. + * is stored in the array auxvt. For details see linux/fs/binfmt_elf.c where
  743. + * it calls NEW_AUX_ENT() a bunch of times....
  744. *
  745. * Next, we need to find the GOT. On most arches there is a register pointing
  746. * to the GOT, but just in case (and for new ports) I've added some (slow) C
  747. diff -Nur uClibc-0.9.32-rc3/ldso/ldso/frv/dl-inlines.h uClibc/ldso/ldso/frv/dl-inlines.h
  748. --- uClibc-0.9.32-rc3/ldso/ldso/frv/dl-inlines.h 2011-03-16 20:11:13.000000000 +0100
  749. +++ uClibc/ldso/ldso/frv/dl-inlines.h 2011-04-26 16:18:21.757661905 +0200
  750. @@ -72,14 +72,39 @@
  751. segdata->p_memsz = phdr->p_memsz;
  752. #if defined (__SUPPORT_LD_DEBUG__)
  753. - {
  754. - extern char *_dl_debug;
  755. - extern int _dl_debug_file;
  756. - if (_dl_debug)
  757. - _dl_dprintf(_dl_debug_file, "%i: mapped %x at %x, size %x\n",
  758. - loadaddr.map->nsegs-1,
  759. - segdata->p_vaddr, segdata->addr, segdata->p_memsz);
  760. - }
  761. + if (_dl_debug)
  762. + _dl_dprintf(_dl_debug_file, "%i: mapped %x at %x, size %x\n",
  763. + loadaddr.map->nsegs-1,
  764. + segdata->p_vaddr, segdata->addr, segdata->p_memsz);
  765. +#endif
  766. +}
  767. +
  768. +/* Replace an existing entry in the load map. */
  769. +static __always_inline void
  770. +__dl_update_loadaddr_hdr (struct elf32_fdpic_loadaddr loadaddr, void *addr,
  771. + Elf32_Phdr *phdr)
  772. +{
  773. + struct elf32_fdpic_loadseg *segdata;
  774. + void *oldaddr;
  775. + int i;
  776. +
  777. + for (i = 0; i < loadaddr.map->nsegs; i++)
  778. + if (loadaddr.map->segs[i].p_vaddr == phdr->p_vaddr
  779. + && loadaddr.map->segs[i].p_memsz == phdr->p_memsz)
  780. + break;
  781. + if (i == loadaddr.map->nsegs)
  782. + _dl_exit (-1);
  783. +
  784. + segdata = loadaddr.map->segs + i;
  785. + oldaddr = (void *)segdata->addr;
  786. + _dl_munmap (oldaddr, segdata->p_memsz);
  787. + segdata->addr = (Elf32_Addr) addr;
  788. +
  789. +#if defined (__SUPPORT_LD_DEBUG__)
  790. + if (_dl_debug)
  791. + _dl_dprintf(_dl_debug_file, "%i: changed mapping %x at %x (old %x), size %x\n",
  792. + loadaddr.map->nsegs-1,
  793. + segdata->p_vaddr, segdata->addr, oldaddr, segdata->p_memsz);
  794. #endif
  795. }
  796. diff -Nur uClibc-0.9.32-rc3/ldso/ldso/frv/dl-sysdep.h uClibc/ldso/ldso/frv/dl-sysdep.h
  797. --- uClibc-0.9.32-rc3/ldso/ldso/frv/dl-sysdep.h 2011-03-16 20:11:13.000000000 +0100
  798. +++ uClibc/ldso/ldso/frv/dl-sysdep.h 2011-04-26 16:18:21.757661905 +0200
  799. @@ -95,6 +95,8 @@
  800. #define DL_INIT_LOADADDR_HDR(LOADADDR, ADDR, PHDR) \
  801. (__dl_init_loadaddr_hdr ((LOADADDR), (ADDR), (PHDR), \
  802. dl_init_loadaddr_load_count))
  803. +#define DL_UPDATE_LOADADDR_HDR(LOADADDR, ADDR, PHDR) \
  804. + (__dl_update_loadaddr_hdr ((LOADADDR), (ADDR), (PHDR)))
  805. #define DL_LOADADDR_UNMAP(LOADADDR, LEN) \
  806. (__dl_loadaddr_unmap ((LOADADDR), (NULL)))
  807. #define DL_LIB_UNMAP(LIB, LEN) \
  808. diff -Nur uClibc-0.9.32-rc3/ldso/ldso/mips/elfinterp.c uClibc/ldso/ldso/mips/elfinterp.c
  809. --- uClibc-0.9.32-rc3/ldso/ldso/mips/elfinterp.c 2011-03-16 20:11:13.000000000 +0100
  810. +++ uClibc/ldso/ldso/mips/elfinterp.c 2011-04-26 16:18:21.757661905 +0200
  811. @@ -378,8 +378,11 @@
  812. *got_entry += (unsigned long) tpnt->loadaddr;
  813. }
  814. else {
  815. + struct symbol_ref sym_ref;
  816. + sym_ref.sym = sym;
  817. + sym_ref.tpnt = NULL;
  818. *got_entry = (unsigned long) _dl_find_hash(strtab +
  819. - sym->st_name, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT, NULL);
  820. + sym->st_name, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT, &sym_ref);
  821. }
  822. got_entry++;
  823. diff -Nur uClibc-0.9.32-rc3/libc/inet/resolv.c uClibc/libc/inet/resolv.c
  824. --- uClibc-0.9.32-rc3/libc/inet/resolv.c 2011-03-16 20:11:13.000000000 +0100
  825. +++ uClibc/libc/inet/resolv.c 2011-04-26 16:18:21.767661585 +0200
  826. @@ -3009,7 +3009,7 @@
  827. int m = 0;
  828. /* free nsaddrs[m] if they do not point to nsaddr_list[x] */
  829. while (m < ARRAY_SIZE(_res._u._ext.nsaddrs)) {
  830. - char *p2 = (char*)(_res._u._ext.nsaddrs[m]);
  831. + char *p2 = (char*)(_res._u._ext.nsaddrs[m++]);
  832. if (p2 < p1 || (p2 - p1) > sizeof(_res.nsaddr_list))
  833. free(p2);
  834. }
  835. diff -Nur uClibc-0.9.32-rc3/libc/misc/fts/fts.c uClibc/libc/misc/fts/fts.c
  836. --- uClibc-0.9.32-rc3/libc/misc/fts/fts.c 1970-01-01 01:00:00.000000000 +0100
  837. +++ uClibc/libc/misc/fts/fts.c 2011-04-26 16:18:21.777663244 +0200
  838. @@ -0,0 +1,1145 @@
  839. +/*-
  840. + * Copyright (c) 1990, 1993, 1994
  841. + * The Regents of the University of California. All rights reserved.
  842. + *
  843. + * Redistribution and use in source and binary forms, with or without
  844. + * modification, are permitted provided that the following conditions
  845. + * are met:
  846. + * 1. Redistributions of source code must retain the above copyright
  847. + * notice, this list of conditions and the following disclaimer.
  848. + * 2. Redistributions in binary form must reproduce the above copyright
  849. + * notice, this list of conditions and the following disclaimer in the
  850. + * documentation and/or other materials provided with the distribution.
  851. + * 4. Neither the name of the University nor the names of its contributors
  852. + * may be used to endorse or promote products derived from this software
  853. + * without specific prior written permission.
  854. + *
  855. + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  856. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  857. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  858. + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  859. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  860. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  861. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  862. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  863. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  864. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  865. + * SUCH DAMAGE.
  866. + */
  867. +
  868. +#include <sys/param.h>
  869. +#include <sys/stat.h>
  870. +#include <fcntl.h>
  871. +#include <dirent.h>
  872. +#include <errno.h>
  873. +#include <fts.h>
  874. +#include <stdlib.h>
  875. +#include <string.h>
  876. +#include <unistd.h>
  877. +
  878. +#ifdef __UCLIBC_HAS_LFS__
  879. +# include <_lfs_64.h>
  880. +#else
  881. +# define stat64 stat
  882. +# define fstat64 fstat
  883. +#endif
  884. +
  885. +/* Largest alignment size needed, minus one.
  886. + Usually long double is the worst case. */
  887. +#ifndef ALIGNBYTES
  888. +#define ALIGNBYTES (__alignof__ (long double) - 1)
  889. +#endif
  890. +/* Align P to that size. */
  891. +#ifndef ALIGN
  892. +#define ALIGN(p) (((unsigned long int) (p) + ALIGNBYTES) & ~ALIGNBYTES)
  893. +#endif
  894. +
  895. +
  896. +static FTSENT *fts_alloc (FTS *, const char *, size_t) internal_function;
  897. +static FTSENT *fts_build (FTS *, int) internal_function;
  898. +static void fts_lfree (FTSENT *) internal_function;
  899. +static void fts_load (FTS *, FTSENT *) internal_function;
  900. +static size_t fts_maxarglen (char * const *) internal_function;
  901. +static void fts_padjust (FTS *, FTSENT *) internal_function;
  902. +static int fts_palloc (FTS *, size_t) internal_function;
  903. +static FTSENT *fts_sort (FTS *, FTSENT *, int) internal_function;
  904. +static u_short fts_stat (FTS *, FTSENT *, int) internal_function;
  905. +static int fts_safe_changedir (FTS *, FTSENT *, int, const char *)
  906. + internal_function;
  907. +
  908. +#ifndef MAX
  909. +#define MAX(a, b) ({ __typeof__ (a) _a = (a); \
  910. + __typeof__ (b) _b = (b); \
  911. + _a > _b ? _a : _b; })
  912. +#endif
  913. +
  914. +#define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
  915. +
  916. +#define CLR(opt) (sp->fts_options &= ~(opt))
  917. +#define ISSET(opt) (sp->fts_options & (opt))
  918. +#define SET(opt) (sp->fts_options |= (opt))
  919. +
  920. +#define FCHDIR(sp, fd) (!ISSET(FTS_NOCHDIR) && fchdir(fd))
  921. +
  922. +/* fts_build flags */
  923. +#define BCHILD 1 /* fts_children */
  924. +#define BNAMES 2 /* fts_children, names only */
  925. +#define BREAD 3 /* fts_read */
  926. +
  927. +FTS *
  928. +fts_open(argv, options, compar)
  929. + char * const *argv;
  930. + register int options;
  931. + int (*compar) (const FTSENT **, const FTSENT **);
  932. +{
  933. + register FTS *sp;
  934. + register FTSENT *p, *root;
  935. + register int nitems;
  936. + FTSENT *parent = NULL;
  937. + FTSENT *tmp = NULL;
  938. +
  939. + /* Options check. */
  940. + if (options & ~FTS_OPTIONMASK) {
  941. + __set_errno (EINVAL);
  942. + return (NULL);
  943. + }
  944. +
  945. + /* Allocate/initialize the stream */
  946. + if ((sp = malloc((u_int)sizeof(FTS))) == NULL)
  947. + return (NULL);
  948. + memset(sp, 0, sizeof(FTS));
  949. + sp->fts_compar = (int (*) (const void *, const void *)) compar;
  950. + sp->fts_options = options;
  951. +
  952. + /* Logical walks turn on NOCHDIR; symbolic links are too hard. */
  953. + if (ISSET(FTS_LOGICAL))
  954. + SET(FTS_NOCHDIR);
  955. +
  956. + /*
  957. + * Start out with 1K of path space, and enough, in any case,
  958. + * to hold the user's paths.
  959. + */
  960. +#ifndef MAXPATHLEN
  961. +#define MAXPATHLEN 1024
  962. +#endif
  963. + size_t maxarglen = fts_maxarglen(argv);
  964. + if (fts_palloc(sp, MAX(maxarglen, MAXPATHLEN)))
  965. + goto mem1;
  966. +
  967. + /* Allocate/initialize root's parent. */
  968. + if (*argv != NULL) {
  969. + if ((parent = fts_alloc(sp, "", 0)) == NULL)
  970. + goto mem2;
  971. + parent->fts_level = FTS_ROOTPARENTLEVEL;
  972. + }
  973. +
  974. + /* Allocate/initialize root(s). */
  975. + for (root = NULL, nitems = 0; *argv != NULL; ++argv, ++nitems) {
  976. + /* Don't allow zero-length paths. */
  977. + size_t len = strlen(*argv);
  978. + if (len == 0) {
  979. + __set_errno (ENOENT);
  980. + goto mem3;
  981. + }
  982. +
  983. + p = fts_alloc(sp, *argv, len);
  984. + p->fts_level = FTS_ROOTLEVEL;
  985. + p->fts_parent = parent;
  986. + p->fts_accpath = p->fts_name;
  987. + p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW));
  988. +
  989. + /* Command-line "." and ".." are real directories. */
  990. + if (p->fts_info == FTS_DOT)
  991. + p->fts_info = FTS_D;
  992. +
  993. + /*
  994. + * If comparison routine supplied, traverse in sorted
  995. + * order; otherwise traverse in the order specified.
  996. + */
  997. + if (compar) {
  998. + p->fts_link = root;
  999. + root = p;
  1000. + } else {
  1001. + p->fts_link = NULL;
  1002. + if (root == NULL)
  1003. + tmp = root = p;
  1004. + else {
  1005. + tmp->fts_link = p;
  1006. + tmp = p;
  1007. + }
  1008. + }
  1009. + }
  1010. + if (compar && nitems > 1)
  1011. + root = fts_sort(sp, root, nitems);
  1012. +
  1013. + /*
  1014. + * Allocate a dummy pointer and make fts_read think that we've just
  1015. + * finished the node before the root(s); set p->fts_info to FTS_INIT
  1016. + * so that everything about the "current" node is ignored.
  1017. + */
  1018. + if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL)
  1019. + goto mem3;
  1020. + sp->fts_cur->fts_link = root;
  1021. + sp->fts_cur->fts_info = FTS_INIT;
  1022. +
  1023. + /*
  1024. + * If using chdir(2), grab a file descriptor pointing to dot to ensure
  1025. + * that we can get back here; this could be avoided for some paths,
  1026. + * but almost certainly not worth the effort. Slashes, symbolic links,
  1027. + * and ".." are all fairly nasty problems. Note, if we can't get the
  1028. + * descriptor we run anyway, just more slowly.
  1029. + */
  1030. + if (!ISSET(FTS_NOCHDIR)
  1031. + && (sp->fts_rfd = open(".", O_RDONLY, 0)) < 0)
  1032. + SET(FTS_NOCHDIR);
  1033. +
  1034. + return (sp);
  1035. +
  1036. +mem3: fts_lfree(root);
  1037. + free(parent);
  1038. +mem2: free(sp->fts_path);
  1039. +mem1: free(sp);
  1040. + return (NULL);
  1041. +}
  1042. +
  1043. +static void
  1044. +internal_function
  1045. +fts_load(sp, p)
  1046. + FTS *sp;
  1047. + register FTSENT *p;
  1048. +{
  1049. + register int len;
  1050. + register char *cp;
  1051. +
  1052. + /*
  1053. + * Load the stream structure for the next traversal. Since we don't
  1054. + * actually enter the directory until after the preorder visit, set
  1055. + * the fts_accpath field specially so the chdir gets done to the right
  1056. + * place and the user can access the first node. From fts_open it's
  1057. + * known that the path will fit.
  1058. + */
  1059. + len = p->fts_pathlen = p->fts_namelen;
  1060. + memmove(sp->fts_path, p->fts_name, len + 1);
  1061. + if ((cp = strrchr(p->fts_name, '/')) && (cp != p->fts_name || cp[1])) {
  1062. + len = strlen(++cp);
  1063. + memmove(p->fts_name, cp, len + 1);
  1064. + p->fts_namelen = len;
  1065. + }
  1066. + p->fts_accpath = p->fts_path = sp->fts_path;
  1067. + sp->fts_dev = p->fts_dev;
  1068. +}
  1069. +
  1070. +int
  1071. +fts_close(sp)
  1072. + FTS *sp;
  1073. +{
  1074. + register FTSENT *freep, *p;
  1075. + int saved_errno;
  1076. +
  1077. + /*
  1078. + * This still works if we haven't read anything -- the dummy structure
  1079. + * points to the root list, so we step through to the end of the root
  1080. + * list which has a valid parent pointer.
  1081. + */
  1082. + if (sp->fts_cur) {
  1083. + for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) {
  1084. + freep = p;
  1085. + p = p->fts_link != NULL ? p->fts_link : p->fts_parent;
  1086. + free(freep);
  1087. + }
  1088. + free(p);
  1089. + }
  1090. +
  1091. + /* Free up child linked list, sort array, path buffer. */
  1092. + if (sp->fts_child)
  1093. + fts_lfree(sp->fts_child);
  1094. + free(sp->fts_array);
  1095. + free(sp->fts_path);
  1096. +
  1097. + /* Return to original directory, save errno if necessary. */
  1098. + if (!ISSET(FTS_NOCHDIR)) {
  1099. + saved_errno = fchdir(sp->fts_rfd) ? errno : 0;
  1100. + (void)close(sp->fts_rfd);
  1101. +
  1102. + /* Set errno and return. */
  1103. + if (saved_errno != 0) {
  1104. + /* Free up the stream pointer. */
  1105. + free(sp);
  1106. + __set_errno (saved_errno);
  1107. + return (-1);
  1108. + }
  1109. + }
  1110. +
  1111. + /* Free up the stream pointer. */
  1112. + free(sp);
  1113. + return (0);
  1114. +}
  1115. +
  1116. +/*
  1117. + * Special case of "/" at the end of the path so that slashes aren't
  1118. + * appended which would cause paths to be written as "....//foo".
  1119. + */
  1120. +#define NAPPEND(p) \
  1121. + (p->fts_path[p->fts_pathlen - 1] == '/' \
  1122. + ? p->fts_pathlen - 1 : p->fts_pathlen)
  1123. +
  1124. +FTSENT *
  1125. +fts_read(sp)
  1126. + register FTS *sp;
  1127. +{
  1128. + register FTSENT *p, *tmp;
  1129. + register int instr;
  1130. + register char *t;
  1131. + int saved_errno;
  1132. +
  1133. + /* If finished or unrecoverable error, return NULL. */
  1134. + if (sp->fts_cur == NULL || ISSET(FTS_STOP))
  1135. + return (NULL);
  1136. +
  1137. + /* Set current node pointer. */
  1138. + p = sp->fts_cur;
  1139. +
  1140. + /* Save and zero out user instructions. */
  1141. + instr = p->fts_instr;
  1142. + p->fts_instr = FTS_NOINSTR;
  1143. +
  1144. + /* Any type of file may be re-visited; re-stat and re-turn. */
  1145. + if (instr == FTS_AGAIN) {
  1146. + p->fts_info = fts_stat(sp, p, 0);
  1147. + return (p);
  1148. + }
  1149. +
  1150. + /*
  1151. + * Following a symlink -- SLNONE test allows application to see
  1152. + * SLNONE and recover. If indirecting through a symlink, have
  1153. + * keep a pointer to current location. If unable to get that
  1154. + * pointer, follow fails.
  1155. + */
  1156. + if (instr == FTS_FOLLOW &&
  1157. + (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) {
  1158. + p->fts_info = fts_stat(sp, p, 1);
  1159. + if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
  1160. + if ((p->fts_symfd = open(".", O_RDONLY, 0)) < 0) {
  1161. + p->fts_errno = errno;
  1162. + p->fts_info = FTS_ERR;
  1163. + } else
  1164. + p->fts_flags |= FTS_SYMFOLLOW;
  1165. + }
  1166. + return (p);
  1167. + }
  1168. +
  1169. + /* Directory in pre-order. */
  1170. + if (p->fts_info == FTS_D) {
  1171. + /* If skipped or crossed mount point, do post-order visit. */
  1172. + if (instr == FTS_SKIP ||
  1173. + (ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev)) {
  1174. + if (p->fts_flags & FTS_SYMFOLLOW)
  1175. + (void)close(p->fts_symfd);
  1176. + if (sp->fts_child) {
  1177. + fts_lfree(sp->fts_child);
  1178. + sp->fts_child = NULL;
  1179. + }
  1180. + p->fts_info = FTS_DP;
  1181. + return (p);
  1182. + }
  1183. +
  1184. + /* Rebuild if only read the names and now traversing. */
  1185. + if (sp->fts_child != NULL && ISSET(FTS_NAMEONLY)) {
  1186. + CLR(FTS_NAMEONLY);
  1187. + fts_lfree(sp->fts_child);
  1188. + sp->fts_child = NULL;
  1189. + }
  1190. +
  1191. + /*
  1192. + * Cd to the subdirectory.
  1193. + *
  1194. + * If have already read and now fail to chdir, whack the list
  1195. + * to make the names come out right, and set the parent errno
  1196. + * so the application will eventually get an error condition.
  1197. + * Set the FTS_DONTCHDIR flag so that when we logically change
  1198. + * directories back to the parent we don't do a chdir.
  1199. + *
  1200. + * If haven't read do so. If the read fails, fts_build sets
  1201. + * FTS_STOP or the fts_info field of the node.
  1202. + */
  1203. + if (sp->fts_child != NULL) {
  1204. + if (fts_safe_changedir(sp, p, -1, p->fts_accpath)) {
  1205. + p->fts_errno = errno;
  1206. + p->fts_flags |= FTS_DONTCHDIR;
  1207. + for (p = sp->fts_child; p != NULL;
  1208. + p = p->fts_link)
  1209. + p->fts_accpath =
  1210. + p->fts_parent->fts_accpath;
  1211. + }
  1212. + } else if ((sp->fts_child = fts_build(sp, BREAD)) == NULL) {
  1213. + if (ISSET(FTS_STOP))
  1214. + return (NULL);
  1215. + return (p);
  1216. + }
  1217. + p = sp->fts_child;
  1218. + sp->fts_child = NULL;
  1219. + sp->fts_cur = p;
  1220. + goto name;
  1221. + }
  1222. +
  1223. + /* Move to the next node on this level. */
  1224. +next: tmp = p;
  1225. + if ((p = p->fts_link) != NULL) {
  1226. + sp->fts_cur = p;
  1227. + free(tmp);
  1228. +
  1229. + /*
  1230. + * If reached the top, return to the original directory (or
  1231. + * the root of the tree), and load the paths for the next root.
  1232. + */
  1233. + if (p->fts_level == FTS_ROOTLEVEL) {
  1234. + if (FCHDIR(sp, sp->fts_rfd)) {
  1235. + SET(FTS_STOP);
  1236. + return (NULL);
  1237. + }
  1238. + fts_load(sp, p);
  1239. + return p;
  1240. + }
  1241. +
  1242. + /*
  1243. + * User may have called fts_set on the node. If skipped,
  1244. + * ignore. If followed, get a file descriptor so we can
  1245. + * get back if necessary.
  1246. + */
  1247. + if (p->fts_instr == FTS_SKIP)
  1248. + goto next;
  1249. + if (p->fts_instr == FTS_FOLLOW) {
  1250. + p->fts_info = fts_stat(sp, p, 1);
  1251. + if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
  1252. + if ((p->fts_symfd =
  1253. + open(".", O_RDONLY, 0)) < 0) {
  1254. + p->fts_errno = errno;
  1255. + p->fts_info = FTS_ERR;
  1256. + } else
  1257. + p->fts_flags |= FTS_SYMFOLLOW;
  1258. + }
  1259. + p->fts_instr = FTS_NOINSTR;
  1260. + }
  1261. +
  1262. +name: t = sp->fts_path + NAPPEND(p->fts_parent);
  1263. + *t++ = '/';
  1264. + memmove(t, p->fts_name, p->fts_namelen + 1);
  1265. + return p;
  1266. + }
  1267. +
  1268. + /* Move up to the parent node. */
  1269. + p = tmp->fts_parent;
  1270. + sp->fts_cur = p;
  1271. + free(tmp);
  1272. +
  1273. + if (p->fts_level == FTS_ROOTPARENTLEVEL) {
  1274. + /*
  1275. + * Done; free everything up and set errno to 0 so the user
  1276. + * can distinguish between error and EOF.
  1277. + */
  1278. + free(p);
  1279. + __set_errno (0);
  1280. + return (sp->fts_cur = NULL);
  1281. + }
  1282. +
  1283. + /* NUL terminate the pathname. */
  1284. + sp->fts_path[p->fts_pathlen] = '\0';
  1285. +
  1286. + /*
  1287. + * Return to the parent directory. If at a root node or came through
  1288. + * a symlink, go back through the file descriptor. Otherwise, cd up
  1289. + * one directory.
  1290. + */
  1291. + if (p->fts_level == FTS_ROOTLEVEL) {
  1292. + if (FCHDIR(sp, sp->fts_rfd)) {
  1293. + SET(FTS_STOP);
  1294. + return (NULL);
  1295. + }
  1296. + } else if (p->fts_flags & FTS_SYMFOLLOW) {
  1297. + if (FCHDIR(sp, p->fts_symfd)) {
  1298. + saved_errno = errno;
  1299. + (void)close(p->fts_symfd);
  1300. + __set_errno (saved_errno);
  1301. + SET(FTS_STOP);
  1302. + return (NULL);
  1303. + }
  1304. + (void)close(p->fts_symfd);
  1305. + } else if (!(p->fts_flags & FTS_DONTCHDIR) &&
  1306. + fts_safe_changedir(sp, p->fts_parent, -1, "..")) {
  1307. + SET(FTS_STOP);
  1308. + return (NULL);
  1309. + }
  1310. + p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP;
  1311. + return p;
  1312. +}
  1313. +
  1314. +/*
  1315. + * Fts_set takes the stream as an argument although it's not used in this
  1316. + * implementation; it would be necessary if anyone wanted to add global
  1317. + * semantics to fts using fts_set. An error return is allowed for similar
  1318. + * reasons.
  1319. + */
  1320. +/* ARGSUSED */
  1321. +int
  1322. +fts_set(sp, p, instr)
  1323. + FTS *sp;
  1324. + FTSENT *p;
  1325. + int instr;
  1326. +{
  1327. + if (instr != 0 && instr != FTS_AGAIN && instr != FTS_FOLLOW &&
  1328. + instr != FTS_NOINSTR && instr != FTS_SKIP) {
  1329. + __set_errno (EINVAL);
  1330. + return (1);
  1331. + }
  1332. + p->fts_instr = instr;
  1333. + return (0);
  1334. +}
  1335. +
  1336. +FTSENT *
  1337. +fts_children(sp, instr)
  1338. + register FTS *sp;
  1339. + int instr;
  1340. +{
  1341. + register FTSENT *p;
  1342. + int fd;
  1343. +
  1344. + if (instr != 0 && instr != FTS_NAMEONLY) {
  1345. + __set_errno (EINVAL);
  1346. + return (NULL);
  1347. + }
  1348. +
  1349. + /* Set current node pointer. */
  1350. + p = sp->fts_cur;
  1351. +
  1352. + /*
  1353. + * Errno set to 0 so user can distinguish empty directory from
  1354. + * an error.
  1355. + */
  1356. + __set_errno (0);
  1357. +
  1358. + /* Fatal errors stop here. */
  1359. + if (ISSET(FTS_STOP))
  1360. + return (NULL);
  1361. +
  1362. + /* Return logical hierarchy of user's arguments. */
  1363. + if (p->fts_info == FTS_INIT)
  1364. + return (p->fts_link);
  1365. +
  1366. + /*
  1367. + * If not a directory being visited in pre-order, stop here. Could
  1368. + * allow FTS_DNR, assuming the user has fixed the problem, but the
  1369. + * same effect is available with FTS_AGAIN.
  1370. + */
  1371. + if (p->fts_info != FTS_D /* && p->fts_info != FTS_DNR */)
  1372. + return (NULL);
  1373. +
  1374. + /* Free up any previous child list. */
  1375. + if (sp->fts_child != NULL)
  1376. + fts_lfree(sp->fts_child);
  1377. +
  1378. + if (instr == FTS_NAMEONLY) {
  1379. + SET(FTS_NAMEONLY);
  1380. + instr = BNAMES;
  1381. + } else
  1382. + instr = BCHILD;
  1383. +
  1384. + /*
  1385. + * If using chdir on a relative path and called BEFORE fts_read does
  1386. + * its chdir to the root of a traversal, we can lose -- we need to
  1387. + * chdir into the subdirectory, and we don't know where the current
  1388. + * directory is, so we can't get back so that the upcoming chdir by
  1389. + * fts_read will work.
  1390. + */
  1391. + if (p->fts_level != FTS_ROOTLEVEL || p->fts_accpath[0] == '/' ||
  1392. + ISSET(FTS_NOCHDIR))
  1393. + return (sp->fts_child = fts_build(sp, instr));
  1394. +
  1395. + if ((fd = open(".", O_RDONLY, 0)) < 0)
  1396. + return (NULL);
  1397. + sp->fts_child = fts_build(sp, instr);
  1398. + if (fchdir(fd))
  1399. + return (NULL);
  1400. + (void)close(fd);
  1401. + return (sp->fts_child);
  1402. +}
  1403. +
  1404. +/*
  1405. + * This is the tricky part -- do not casually change *anything* in here. The
  1406. + * idea is to build the linked list of entries that are used by fts_children
  1407. + * and fts_read. There are lots of special cases.
  1408. + *
  1409. + * The real slowdown in walking the tree is the stat calls. If FTS_NOSTAT is
  1410. + * set and it's a physical walk (so that symbolic links can't be directories),
  1411. + * we can do things quickly. First, if it's a 4.4BSD file system, the type
  1412. + * of the file is in the directory entry. Otherwise, we assume that the number
  1413. + * of subdirectories in a node is equal to the number of links to the parent.
  1414. + * The former skips all stat calls. The latter skips stat calls in any leaf
  1415. + * directories and for any files after the subdirectories in the directory have
  1416. + * been found, cutting the stat calls by about 2/3.
  1417. + */
  1418. +static FTSENT *
  1419. +internal_function
  1420. +fts_build(sp, type)
  1421. + register FTS *sp;
  1422. + int type;
  1423. +{
  1424. + register struct dirent *dp;
  1425. + register FTSENT *p, *head;
  1426. + register int nitems;
  1427. + FTSENT *cur, *tail;
  1428. + DIR *dirp;
  1429. + void *oldaddr;
  1430. + int cderrno, descend, len, level, nlinks, saved_errno,
  1431. + nostat, doadjust;
  1432. + size_t maxlen;
  1433. + char *cp;
  1434. +
  1435. + /* Set current node pointer. */
  1436. + cur = sp->fts_cur;
  1437. +
  1438. + /*
  1439. + * Open the directory for reading. If this fails, we're done.
  1440. + * If being called from fts_read, set the fts_info field.
  1441. + */
  1442. +#if defined FTS_WHITEOUT && 0
  1443. + if (ISSET(FTS_WHITEOUT))
  1444. + oflag = DTF_NODUP|DTF_REWIND;
  1445. + else
  1446. + oflag = DTF_HIDEW|DTF_NODUP|DTF_REWIND;
  1447. +#else
  1448. +# define opendir2(path, flag) opendir(path)
  1449. +#endif
  1450. + if ((dirp = opendir2(cur->fts_accpath, oflag)) == NULL) {
  1451. + if (type == BREAD) {
  1452. + cur->fts_info = FTS_DNR;
  1453. + cur->fts_errno = errno;
  1454. + }
  1455. + return (NULL);
  1456. + }
  1457. +
  1458. + /*
  1459. + * Nlinks is the number of possible entries of type directory in the
  1460. + * directory if we're cheating on stat calls, 0 if we're not doing
  1461. + * any stat calls at all, -1 if we're doing stats on everything.
  1462. + */
  1463. + if (type == BNAMES) {
  1464. + nlinks = 0;
  1465. + /* Be quiet about nostat, GCC. */
  1466. + nostat = 0;
  1467. + } else if (ISSET(FTS_NOSTAT) && ISSET(FTS_PHYSICAL)) {
  1468. + nlinks = cur->fts_nlink - (ISSET(FTS_SEEDOT) ? 0 : 2);
  1469. + nostat = 1;
  1470. + } else {
  1471. + nlinks = -1;
  1472. + nostat = 0;
  1473. + }
  1474. +
  1475. +#ifdef notdef
  1476. + (void)printf("nlinks == %d (cur: %d)\n", nlinks, cur->fts_nlink);
  1477. + (void)printf("NOSTAT %d PHYSICAL %d SEEDOT %d\n",
  1478. + ISSET(FTS_NOSTAT), ISSET(FTS_PHYSICAL), ISSET(FTS_SEEDOT));
  1479. +#endif
  1480. + /*
  1481. + * If we're going to need to stat anything or we want to descend
  1482. + * and stay in the directory, chdir. If this fails we keep going,
  1483. + * but set a flag so we don't chdir after the post-order visit.
  1484. + * We won't be able to stat anything, but we can still return the
  1485. + * names themselves. Note, that since fts_read won't be able to
  1486. + * chdir into the directory, it will have to return different path
  1487. + * names than before, i.e. "a/b" instead of "b". Since the node
  1488. + * has already been visited in pre-order, have to wait until the
  1489. + * post-order visit to return the error. There is a special case
  1490. + * here, if there was nothing to stat then it's not an error to
  1491. + * not be able to stat. This is all fairly nasty. If a program
  1492. + * needed sorted entries or stat information, they had better be
  1493. + * checking FTS_NS on the returned nodes.
  1494. + */
  1495. + cderrno = 0;
  1496. + if (nlinks || type == BREAD) {
  1497. + if (fts_safe_changedir(sp, cur, dirfd(dirp), NULL)) {
  1498. + if (nlinks && type == BREAD)
  1499. + cur->fts_errno = errno;
  1500. + cur->fts_flags |= FTS_DONTCHDIR;
  1501. + descend = 0;
  1502. + cderrno = errno;
  1503. + (void)closedir(dirp);
  1504. + dirp = NULL;
  1505. + } else
  1506. + descend = 1;
  1507. + } else
  1508. + descend = 0;
  1509. +
  1510. + /*
  1511. + * Figure out the max file name length that can be stored in the
  1512. + * current path -- the inner loop allocates more path as necessary.
  1513. + * We really wouldn't have to do the maxlen calculations here, we
  1514. + * could do them in fts_read before returning the path, but it's a
  1515. + * lot easier here since the length is part of the dirent structure.
  1516. + *
  1517. + * If not changing directories set a pointer so that can just append
  1518. + * each new name into the path.
  1519. + */
  1520. + len = NAPPEND(cur);
  1521. + if (ISSET(FTS_NOCHDIR)) {
  1522. + cp = sp->fts_path + len;
  1523. + *cp++ = '/';
  1524. + } else {
  1525. + /* GCC, you're too verbose. */
  1526. + cp = NULL;
  1527. + }
  1528. + len++;
  1529. + maxlen = sp->fts_pathlen - len;
  1530. +
  1531. + level = cur->fts_level + 1;
  1532. +
  1533. + /* Read the directory, attaching each entry to the `link' pointer. */
  1534. + doadjust = 0;
  1535. + for (head = tail = NULL, nitems = 0; dirp && (dp = readdir(dirp));) {
  1536. + if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name))
  1537. + continue;
  1538. +
  1539. + if ((p = fts_alloc(sp, dp->d_name, _D_EXACT_NAMLEN (dp))) == NULL)
  1540. + goto mem1;
  1541. + if (_D_EXACT_NAMLEN (dp) >= maxlen) {/* include space for NUL */
  1542. + oldaddr = sp->fts_path;
  1543. + if (fts_palloc(sp, _D_EXACT_NAMLEN (dp) + len + 1)) {
  1544. + /*
  1545. + * No more memory for path or structures. Save
  1546. + * errno, free up the current structure and the
  1547. + * structures already allocated.
  1548. + */
  1549. +mem1: saved_errno = errno;
  1550. + free(p);
  1551. + fts_lfree(head);
  1552. + (void)closedir(dirp);
  1553. + cur->fts_info = FTS_ERR;
  1554. + SET(FTS_STOP);
  1555. + __set_errno (saved_errno);
  1556. + return (NULL);
  1557. + }
  1558. + /* Did realloc() change the pointer? */
  1559. + if (oldaddr != sp->fts_path) {
  1560. + doadjust = 1;
  1561. + if (ISSET(FTS_NOCHDIR))
  1562. + cp = sp->fts_path + len;
  1563. + }
  1564. + maxlen = sp->fts_pathlen - len;
  1565. + }
  1566. +
  1567. + if (len + _D_EXACT_NAMLEN (dp) >= USHRT_MAX) {
  1568. + /*
  1569. + * In an FTSENT, fts_pathlen is a u_short so it is
  1570. + * possible to wraparound here. If we do, free up
  1571. + * the current structure and the structures already
  1572. + * allocated, then error out with ENAMETOOLONG.
  1573. + */
  1574. + free(p);
  1575. + fts_lfree(head);
  1576. + (void)closedir(dirp);
  1577. + cur->fts_info = FTS_ERR;
  1578. + SET(FTS_STOP);
  1579. + __set_errno (ENAMETOOLONG);
  1580. + return (NULL);
  1581. + }
  1582. + p->fts_level = level;
  1583. + p->fts_parent = sp->fts_cur;
  1584. + p->fts_pathlen = len + _D_EXACT_NAMLEN (dp);
  1585. +
  1586. +#if defined FTS_WHITEOUT && 0
  1587. + if (dp->d_type == DT_WHT)
  1588. + p->fts_flags |= FTS_ISW;
  1589. +#endif
  1590. +
  1591. +#if 0
  1592. + /* Unreachable code. cderrno is only ever set to a nonnull
  1593. + value if dirp is closed at the same time. But then we
  1594. + cannot enter this loop. */
  1595. + if (cderrno) {
  1596. + if (nlinks) {
  1597. + p->fts_info = FTS_NS;
  1598. + p->fts_errno = cderrno;
  1599. + } else
  1600. + p->fts_info = FTS_NSOK;
  1601. + p->fts_accpath = cur->fts_accpath;
  1602. + } else
  1603. +#endif
  1604. + if (nlinks == 0
  1605. +#if defined DT_DIR && defined _DIRENT_HAVE_D_TYPE
  1606. + || (nostat &&
  1607. + dp->d_type != DT_DIR && dp->d_type != DT_UNKNOWN)
  1608. +#endif
  1609. + ) {
  1610. + p->fts_accpath =
  1611. + ISSET(FTS_NOCHDIR) ? p->fts_path : p->fts_name;
  1612. + p->fts_info = FTS_NSOK;
  1613. + } else {
  1614. + /* Build a file name for fts_stat to stat. */
  1615. + if (ISSET(FTS_NOCHDIR)) {
  1616. + p->fts_accpath = p->fts_path;
  1617. + memmove(cp, p->fts_name, p->fts_namelen + 1);
  1618. + } else
  1619. + p->fts_accpath = p->fts_name;
  1620. + /* Stat it. */
  1621. + p->fts_info = fts_stat(sp, p, 0);
  1622. +
  1623. + /* Decrement link count if applicable. */
  1624. + if (nlinks > 0 && (p->fts_info == FTS_D ||
  1625. + p->fts_info == FTS_DC || p->fts_info == FTS_DOT))
  1626. + --nlinks;
  1627. + }
  1628. +
  1629. + /* We walk in directory order so "ls -f" doesn't get upset. */
  1630. + p->fts_link = NULL;
  1631. + if (head == NULL)
  1632. + head = tail = p;
  1633. + else {
  1634. + tail->fts_link = p;
  1635. + tail = p;
  1636. + }
  1637. + ++nitems;
  1638. + }
  1639. + if (dirp)
  1640. + (void)closedir(dirp);
  1641. +
  1642. + /*
  1643. + * If realloc() changed the address of the path, adjust the
  1644. + * addresses for the rest of the tree and the dir list.
  1645. + */
  1646. + if (doadjust)
  1647. + fts_padjust(sp, head);
  1648. +
  1649. + /*
  1650. + * If not changing directories, reset the path back to original
  1651. + * state.
  1652. + */
  1653. + if (ISSET(FTS_NOCHDIR)) {
  1654. + if (len == sp->fts_pathlen || nitems == 0)
  1655. + --cp;
  1656. + *cp = '\0';
  1657. + }
  1658. +
  1659. + /*
  1660. + * If descended after called from fts_children or after called from
  1661. + * fts_read and nothing found, get back. At the root level we use
  1662. + * the saved fd; if one of fts_open()'s arguments is a relative path
  1663. + * to an empty directory, we wind up here with no other way back. If
  1664. + * can't get back, we're done.
  1665. + */
  1666. + if (descend && (type == BCHILD || !nitems) &&
  1667. + (cur->fts_level == FTS_ROOTLEVEL ?
  1668. + FCHDIR(sp, sp->fts_rfd) :
  1669. + fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) {
  1670. + cur->fts_info = FTS_ERR;
  1671. + SET(FTS_STOP);
  1672. + fts_lfree(head);
  1673. + return (NULL);
  1674. + }
  1675. +
  1676. + /* If didn't find anything, return NULL. */
  1677. + if (!nitems) {
  1678. + if (type == BREAD)
  1679. + cur->fts_info = FTS_DP;
  1680. + fts_lfree(head);
  1681. + return (NULL);
  1682. + }
  1683. +
  1684. + /* Sort the entries. */
  1685. + if (sp->fts_compar && nitems > 1)
  1686. + head = fts_sort(sp, head, nitems);
  1687. + return (head);
  1688. +}
  1689. +
  1690. +static u_short
  1691. +internal_function
  1692. +fts_stat(sp, p, follow)
  1693. + FTS *sp;
  1694. + register FTSENT *p;
  1695. + int follow;
  1696. +{
  1697. + register FTSENT *t;
  1698. + register dev_t dev;
  1699. + register ino_t ino;
  1700. + struct stat *sbp, sb;
  1701. + int saved_errno;
  1702. +
  1703. + /* If user needs stat info, stat buffer already allocated. */
  1704. + sbp = ISSET(FTS_NOSTAT) ? &sb : p->fts_statp;
  1705. +
  1706. +#if defined FTS_WHITEOUT && 0
  1707. + /* check for whiteout */
  1708. + if (p->fts_flags & FTS_ISW) {
  1709. + if (sbp != &sb) {
  1710. + memset(sbp, '\0', sizeof (*sbp));
  1711. + sbp->st_mode = S_IFWHT;
  1712. + }
  1713. + return (FTS_W);
  1714. + }
  1715. +#endif
  1716. +
  1717. + /*
  1718. + * If doing a logical walk, or application requested FTS_FOLLOW, do
  1719. + * a stat(2). If that fails, check for a non-existent symlink. If
  1720. + * fail, set the errno from the stat call.
  1721. + */
  1722. + if (ISSET(FTS_LOGICAL) || follow) {
  1723. + if (stat(p->fts_accpath, sbp)) {
  1724. + saved_errno = errno;
  1725. + if (!lstat(p->fts_accpath, sbp)) {
  1726. + __set_errno (0);
  1727. + return (FTS_SLNONE);
  1728. + }
  1729. + p->fts_errno = saved_errno;
  1730. + goto err;
  1731. + }
  1732. + } else if (lstat(p->fts_accpath, sbp)) {
  1733. + p->fts_errno = errno;
  1734. +err: memset(sbp, 0, sizeof(struct stat));
  1735. + return (FTS_NS);
  1736. + }
  1737. +
  1738. + if (S_ISDIR(sbp->st_mode)) {
  1739. + /*
  1740. + * Set the device/inode. Used to find cycles and check for
  1741. + * crossing mount points. Also remember the link count, used
  1742. + * in fts_build to limit the number of stat calls. It is
  1743. + * understood that these fields are only referenced if fts_info
  1744. + * is set to FTS_D.
  1745. + */
  1746. + dev = p->fts_dev = sbp->st_dev;
  1747. + ino = p->fts_ino = sbp->st_ino;
  1748. + p->fts_nlink = sbp->st_nlink;
  1749. +
  1750. + if (ISDOT(p->fts_name))
  1751. + return (FTS_DOT);
  1752. +
  1753. + /*
  1754. + * Cycle detection is done by brute force when the directory
  1755. + * is first encountered. If the tree gets deep enough or the
  1756. + * number of symbolic links to directories is high enough,
  1757. + * something faster might be worthwhile.
  1758. + */
  1759. + for (t = p->fts_parent;
  1760. + t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent)
  1761. + if (ino == t->fts_ino && dev == t->fts_dev) {
  1762. + p->fts_cycle = t;
  1763. + return (FTS_DC);
  1764. + }
  1765. + return (FTS_D);
  1766. + }
  1767. + if (S_ISLNK(sbp->st_mode))
  1768. + return (FTS_SL);
  1769. + if (S_ISREG(sbp->st_mode))
  1770. + return (FTS_F);
  1771. + return (FTS_DEFAULT);
  1772. +}
  1773. +
  1774. +static FTSENT *
  1775. +internal_function
  1776. +fts_sort(sp, head, nitems)
  1777. + FTS *sp;
  1778. + FTSENT *head;
  1779. + register int nitems;
  1780. +{
  1781. + register FTSENT **ap, *p;
  1782. +
  1783. + /*
  1784. + * Construct an array of pointers to the structures and call qsort(3).
  1785. + * Reassemble the array in the order returned by qsort. If unable to
  1786. + * sort for memory reasons, return the directory entries in their
  1787. + * current order. Allocate enough space for the current needs plus
  1788. + * 40 so don't realloc one entry at a time.
  1789. + */
  1790. + if (nitems > sp->fts_nitems) {
  1791. + struct _ftsent **a;
  1792. +
  1793. + sp->fts_nitems = nitems + 40;
  1794. + if ((a = realloc(sp->fts_array,
  1795. + (size_t)(sp->fts_nitems * sizeof(FTSENT *)))) == NULL) {
  1796. + free(sp->fts_array);
  1797. + sp->fts_array = NULL;
  1798. + sp->fts_nitems = 0;
  1799. + return (head);
  1800. + }
  1801. + sp->fts_array = a;
  1802. + }
  1803. + for (ap = sp->fts_array, p = head; p; p = p->fts_link)
  1804. + *ap++ = p;
  1805. + qsort((void *)sp->fts_array, nitems, sizeof(FTSENT *), sp->fts_compar);
  1806. + for (head = *(ap = sp->fts_array); --nitems; ++ap)
  1807. + ap[0]->fts_link = ap[1];
  1808. + ap[0]->fts_link = NULL;
  1809. + return (head);
  1810. +}
  1811. +
  1812. +static FTSENT *
  1813. +internal_function
  1814. +fts_alloc(sp, name, namelen)
  1815. + FTS *sp;
  1816. + const char *name;
  1817. + size_t namelen;
  1818. +{
  1819. + register FTSENT *p;
  1820. + size_t len;
  1821. +
  1822. + /*
  1823. + * The file name is a variable length array and no stat structure is
  1824. + * necessary if the user has set the nostat bit. Allocate the FTSENT
  1825. + * structure, the file name and the stat structure in one chunk, but
  1826. + * be careful that the stat structure is reasonably aligned. Since the
  1827. + * fts_name field is declared to be of size 1, the fts_name pointer is
  1828. + * namelen + 2 before the first possible address of the stat structure.
  1829. + */
  1830. + len = sizeof(FTSENT) + namelen;
  1831. + if (!ISSET(FTS_NOSTAT))
  1832. + len += sizeof(struct stat) + ALIGNBYTES;
  1833. + if ((p = malloc(len)) == NULL)
  1834. + return (NULL);
  1835. +
  1836. + /* Copy the name and guarantee NUL termination. */
  1837. + memmove(p->fts_name, name, namelen);
  1838. + p->fts_name[namelen] = '\0';
  1839. +
  1840. + if (!ISSET(FTS_NOSTAT))
  1841. + p->fts_statp = (struct stat *)ALIGN(p->fts_name + namelen + 2);
  1842. + p->fts_namelen = namelen;
  1843. + p->fts_path = sp->fts_path;
  1844. + p->fts_errno = 0;
  1845. + p->fts_flags = 0;
  1846. + p->fts_instr = FTS_NOINSTR;
  1847. + p->fts_number = 0;
  1848. + p->fts_pointer = NULL;
  1849. + return (p);
  1850. +}
  1851. +
  1852. +static void
  1853. +internal_function
  1854. +fts_lfree(head)
  1855. + register FTSENT *head;
  1856. +{
  1857. + register FTSENT *p;
  1858. +
  1859. + /* Free a linked list of structures. */
  1860. + while ((p = head)) {
  1861. + head = head->fts_link;
  1862. + free(p);
  1863. + }
  1864. +}
  1865. +
  1866. +/*
  1867. + * Allow essentially unlimited paths; find, rm, ls should all work on any tree.
  1868. + * Most systems will allow creation of paths much longer than MAXPATHLEN, even
  1869. + * though the kernel won't resolve them. Add the size (not just what's needed)
  1870. + * plus 256 bytes so don't realloc the path 2 bytes at a time.
  1871. + */
  1872. +static int
  1873. +internal_function
  1874. +fts_palloc(sp, more)
  1875. + FTS *sp;
  1876. + size_t more;
  1877. +{
  1878. + char *p;
  1879. +
  1880. + sp->fts_pathlen += more + 256;
  1881. + /*
  1882. + * Check for possible wraparound. In an FTS, fts_pathlen is
  1883. + * a signed int but in an FTSENT it is an unsigned short.
  1884. + * We limit fts_pathlen to USHRT_MAX to be safe in both cases.
  1885. + */
  1886. + if (sp->fts_pathlen < 0 || sp->fts_pathlen >= USHRT_MAX) {
  1887. + free(sp->fts_path);
  1888. + sp->fts_path = NULL;
  1889. + __set_errno (ENAMETOOLONG);
  1890. + return (1);
  1891. + }
  1892. + p = realloc(sp->fts_path, sp->fts_pathlen);
  1893. + if (p == NULL) {
  1894. + free(sp->fts_path);
  1895. + sp->fts_path = NULL;
  1896. + return 1;
  1897. + }
  1898. + sp->fts_path = p;
  1899. + return 0;
  1900. +}
  1901. +
  1902. +/*
  1903. + * When the path is realloc'd, have to fix all of the pointers in structures
  1904. + * already returned.
  1905. + */
  1906. +static void
  1907. +internal_function
  1908. +fts_padjust(sp, head)
  1909. + FTS *sp;
  1910. + FTSENT *head;
  1911. +{
  1912. + FTSENT *p;
  1913. + char *addr = sp->fts_path;
  1914. +
  1915. +#define ADJUST(p) do { \
  1916. + if ((p)->fts_accpath != (p)->fts_name) { \
  1917. + (p)->fts_accpath = \
  1918. + (char *)addr + ((p)->fts_accpath - (p)->fts_path); \
  1919. + } \
  1920. + (p)->fts_path = addr; \
  1921. +} while (0)
  1922. + /* Adjust the current set of children. */
  1923. + for (p = sp->fts_child; p; p = p->fts_link)
  1924. + ADJUST(p);
  1925. +
  1926. + /* Adjust the rest of the tree, including the current level. */
  1927. + for (p = head; p->fts_level >= FTS_ROOTLEVEL;) {
  1928. + ADJUST(p);
  1929. + p = p->fts_link ? p->fts_link : p->fts_parent;
  1930. + }
  1931. +}
  1932. +
  1933. +static size_t
  1934. +internal_function
  1935. +fts_maxarglen(argv)
  1936. + char * const *argv;
  1937. +{
  1938. + size_t len, max;
  1939. +
  1940. + for (max = 0; *argv; ++argv)
  1941. + if ((len = strlen(*argv)) > max)
  1942. + max = len;
  1943. + return (max + 1);
  1944. +}
  1945. +
  1946. +/*
  1947. + * Change to dir specified by fd or p->fts_accpath without getting
  1948. + * tricked by someone changing the world out from underneath us.
  1949. + * Assumes p->fts_dev and p->fts_ino are filled in.
  1950. + */
  1951. +static int
  1952. +internal_function
  1953. +fts_safe_changedir(sp, p, fd, path)
  1954. + FTS *sp;
  1955. + FTSENT *p;
  1956. + int fd;
  1957. + const char *path;
  1958. +{
  1959. + int ret, oerrno, newfd;
  1960. + struct stat64 sb;
  1961. +
  1962. + newfd = fd;
  1963. + if (ISSET(FTS_NOCHDIR))
  1964. + return (0);
  1965. + if (fd < 0 && (newfd = open(path, O_RDONLY, 0)) < 0)
  1966. + return (-1);
  1967. + if (fstat64(newfd, &sb)) {
  1968. + ret = -1;
  1969. + goto bail;
  1970. + }
  1971. + if (p->fts_dev != sb.st_dev || p->fts_ino != sb.st_ino) {
  1972. + __set_errno (ENOENT); /* disinformation */
  1973. + ret = -1;
  1974. + goto bail;
  1975. + }
  1976. + ret = fchdir(newfd);
  1977. +bail:
  1978. + oerrno = errno;
  1979. + if (fd < 0)
  1980. + (void)close(newfd);
  1981. + __set_errno (oerrno);
  1982. + return (ret);
  1983. +}
  1984. diff -Nur uClibc-0.9.32-rc3/libc/misc/fts/Makefile uClibc/libc/misc/fts/Makefile
  1985. --- uClibc-0.9.32-rc3/libc/misc/fts/Makefile 1970-01-01 01:00:00.000000000 +0100
  1986. +++ uClibc/libc/misc/fts/Makefile 2011-04-26 16:18:21.777663244 +0200
  1987. @@ -0,0 +1,14 @@
  1988. +# Makefile for uClibc
  1989. +#
  1990. +# Copyright (C) 2009 STMicroelectronics Ltd.
  1991. +# Author: Salvatore Cro <salvatore.cro at st.com>
  1992. +#
  1993. +# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  1994. +#
  1995. +
  1996. +top_srcdir=../../../
  1997. +top_builddir=../../../
  1998. +all: objs
  1999. +include $(top_builddir)Rules.mak
  2000. +include Makefile.in
  2001. +include $(top_srcdir)Makerules
  2002. diff -Nur uClibc-0.9.32-rc3/libc/misc/fts/Makefile.in uClibc/libc/misc/fts/Makefile.in
  2003. --- uClibc-0.9.32-rc3/libc/misc/fts/Makefile.in 1970-01-01 01:00:00.000000000 +0100
  2004. +++ uClibc/libc/misc/fts/Makefile.in 2011-04-26 16:18:21.777663244 +0200
  2005. @@ -0,0 +1,23 @@
  2006. +# FTS Makefile for uClibc
  2007. +#
  2008. +# Copyright (C) 2009 STMicroelectronics Ltd.
  2009. +# Author: Salvatore Cro <salvatore.cro at st.com>
  2010. +#
  2011. +# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  2012. +#
  2013. +
  2014. +subdirs += libc/misc/fts
  2015. +CSRC := fts.c
  2016. +
  2017. +MISC_FTS_DIR := $(top_srcdir)libc/misc/fts
  2018. +MISC_FTS_OUT := $(top_builddir)libc/misc/fts
  2019. +
  2020. +MISC_FTS_SRC := $(patsubst %.c,$(MISC_FTS_DIR)/%.c,$(CSRC))
  2021. +MISC_FTS_OBJ := $(patsubst %.c,$(MISC_FTS_OUT)/%.o,$(CSRC))
  2022. +
  2023. +libc-$(UCLIBC_HAS_FTS) += $(MISC_FTS_OBJ)
  2024. +
  2025. +objclean-y += CLEAN_libc/misc/fts
  2026. +
  2027. +CLEAN_libc/misc/fts:
  2028. + $(do_rm) $(addprefix $(MISC_FTS_OUT)/*., o os)
  2029. diff -Nur uClibc-0.9.32-rc3/libc/misc/Makefile.in uClibc/libc/misc/Makefile.in
  2030. --- uClibc-0.9.32-rc3/libc/misc/Makefile.in 2011-03-16 20:11:13.000000000 +0100
  2031. +++ uClibc/libc/misc/Makefile.in 2011-04-26 16:18:21.767661585 +0200
  2032. @@ -16,6 +16,7 @@
  2033. include $(top_srcdir)libc/misc/file/Makefile.in
  2034. include $(top_srcdir)libc/misc/fnmatch/Makefile.in
  2035. include $(top_srcdir)libc/misc/ftw/Makefile.in
  2036. +include $(top_srcdir)libc/misc/fts/Makefile.in
  2037. include $(top_srcdir)libc/misc/glob/Makefile.in
  2038. include $(top_srcdir)libc/misc/gnu/Makefile.in
  2039. include $(top_srcdir)libc/misc/internals/Makefile.in
  2040. diff -Nur uClibc-0.9.32-rc3/libc/stdlib/malloc/heap.h uClibc/libc/stdlib/malloc/heap.h
  2041. --- uClibc-0.9.32-rc3/libc/stdlib/malloc/heap.h 2011-03-16 20:11:13.000000000 +0100
  2042. +++ uClibc/libc/stdlib/malloc/heap.h 2011-04-26 16:18:21.888707940 +0200
  2043. @@ -29,8 +29,10 @@
  2044. /* The heap allocates in multiples of, and aligned to, HEAP_GRANULARITY.
  2045. HEAP_GRANULARITY must be a power of 2. Malloc depends on this being the
  2046. same as MALLOC_ALIGNMENT. */
  2047. -#define HEAP_GRANULARITY_TYPE double __attribute_aligned__ (sizeof (size_t))
  2048. -#define HEAP_GRANULARITY (__alignof__ (HEAP_GRANULARITY_TYPE))
  2049. +#define HEAP_GRANULARITY_TYPE double __attribute_aligned__ (HEAP_GRANULARITY)
  2050. +#define HEAP_GRANULARITY \
  2051. + (__alignof__ (double) > sizeof (size_t) ? __alignof__ (double) : sizeof (size_t))
  2052. +
  2053. /* The HEAP_INIT macro can be used as a static initializer for a heap
  2054. diff -Nur uClibc-0.9.32-rc3/libc/stdlib/malloc/malloc.h uClibc/libc/stdlib/malloc/malloc.h
  2055. --- uClibc-0.9.32-rc3/libc/stdlib/malloc/malloc.h 2011-03-16 20:11:13.000000000 +0100
  2056. +++ uClibc/libc/stdlib/malloc/malloc.h 2011-04-26 16:18:21.888707940 +0200
  2057. @@ -17,7 +17,7 @@
  2058. alignment can be a significant win on targets like m68k and Coldfire,
  2059. where __alignof__(double) == 2. */
  2060. #define MALLOC_ALIGNMENT \
  2061. - __alignof__ (double __attribute_aligned__ (sizeof (size_t)))
  2062. + (__alignof__ (double) > sizeof (size_t) ? __alignof__ (double) : sizeof (size_t))
  2063. /* The system pagesize... */
  2064. extern size_t __pagesize;
  2065. diff -Nur uClibc-0.9.32-rc3/libc/sysdeps/linux/common/lutimes.c uClibc/libc/sysdeps/linux/common/lutimes.c
  2066. --- uClibc-0.9.32-rc3/libc/sysdeps/linux/common/lutimes.c 2011-03-16 20:11:13.000000000 +0100
  2067. +++ uClibc/libc/sysdeps/linux/common/lutimes.c 2011-04-26 16:18:22.008914246 +0200
  2068. @@ -12,7 +12,7 @@
  2069. #ifdef __NR_lutimes
  2070. _syscall2(int, lutimes, const char *, file, const struct timeval *, tvp)
  2071. -#else
  2072. +#elif defined __NR_utimensat
  2073. #include <sys/time.h>
  2074. #include <fcntl.h>
  2075. diff -Nur uClibc-0.9.32-rc3/libc/sysdeps/linux/common/Makefile.in uClibc/libc/sysdeps/linux/common/Makefile.in
  2076. --- uClibc-0.9.32-rc3/libc/sysdeps/linux/common/Makefile.in 2011-03-16 20:11:13.000000000 +0100
  2077. +++ uClibc/libc/sysdeps/linux/common/Makefile.in 2011-04-26 16:18:21.927829410 +0200
  2078. @@ -15,7 +15,9 @@
  2079. CSRC-y := $(filter-out llseek.c $(CSRC_LFS),$(CSRC-y))
  2080. CSRC-$(UCLIBC_HAS_LFS) += llseek.c $(CSRC_LFS)
  2081. -CSRC-$(if $(or $(UCLIBC_HAS_SSP),$(UCLIBC_HAS_FORTIFY)),y) += ssp.c
  2082. +ifneq ($(UCLIBC_HAS_SSP)$(UCLIBC_HAS_FORTIFY),)
  2083. +CSRC-y += ssp.c
  2084. +endif
  2085. CSRC-$(UCLIBC_LINUX_MODULE_24) += create_module.c query_module.c \
  2086. get_kernel_syms.c
  2087. # we need these internally: fstatfs.c statfs.c
  2088. @@ -25,7 +27,9 @@
  2089. sendfile64.c sendfile.c setfsgid.c setfsuid.c setresuid.c \
  2090. splice.c vmsplice.c tee.c signalfd.c swapoff.c swapon.c \
  2091. sync_file_range.c sysctl.c sysinfo.c timerfd.c uselib.c vhangup.c
  2092. -CSRC-$(if $(and $(UCLIBC_LINUX_SPECIFIC),$(UCLIBC_HAS_THREADS_NATIVE)),y) += madvise.c
  2093. +ifeq ($(UCLIBC_LINUX_SPECIFIC)$(UCLIBC_HAS_THREADS_NATIVE),yy)
  2094. +CSRC-y += madvise.c
  2095. +endif
  2096. ifeq ($(UCLIBC_HAS_THREADS_NATIVE),y)
  2097. CSRC- += fork.c getpid.c raise.c open.c close.c read.c write.c
  2098. CSRC- += $(if $(findstring =arm=,=$(TARGET_ARCH)=),vfork.c)
  2099. diff -Nur uClibc-0.9.32-rc3/libc/sysdeps/linux/common/stubs.c uClibc/libc/sysdeps/linux/common/stubs.c
  2100. --- uClibc-0.9.32-rc3/libc/sysdeps/linux/common/stubs.c 2011-03-16 20:11:13.000000000 +0100
  2101. +++ uClibc/libc/sysdeps/linux/common/stubs.c 2011-04-26 16:18:22.038918529 +0200
  2102. @@ -172,6 +172,14 @@
  2103. make_stub(umount2)
  2104. #endif
  2105. +#ifndef __NR_utimensat
  2106. +make_stub(futimens)
  2107. +make_stub(utimensat)
  2108. +# ifndef __NR_lutimes
  2109. +make_stub(lutimes)
  2110. +# endif
  2111. +#endif
  2112. +
  2113. #ifndef __NR_vmsplice
  2114. make_stub(vmsplice)
  2115. #endif
  2116. diff -Nur uClibc-0.9.32-rc3/libc/sysdeps/linux/cris/Makefile.arch uClibc/libc/sysdeps/linux/cris/Makefile.arch
  2117. --- uClibc-0.9.32-rc3/libc/sysdeps/linux/cris/Makefile.arch 2011-03-16 20:11:13.000000000 +0100
  2118. +++ uClibc/libc/sysdeps/linux/cris/Makefile.arch 2011-04-26 16:18:22.048914220 +0200
  2119. @@ -7,7 +7,7 @@
  2120. CSRC := __init_brk.c brk.c sbrk.c
  2121. -SSRC := setjmp.S __longjmp.S clone.S sysdep.S syscall.S
  2122. +SSRC := setjmp.S __longjmp.S clone.S sysdep.S syscall.S vfork.S
  2123. ifeq ($(UNIFIED_SYSCALL),y)
  2124. SSRC += __uClibc_syscall.S
  2125. endif
  2126. diff -Nur uClibc-0.9.32-rc3/libc/sysdeps/linux/cris/vfork.S uClibc/libc/sysdeps/linux/cris/vfork.S
  2127. --- uClibc-0.9.32-rc3/libc/sysdeps/linux/cris/vfork.S 1970-01-01 01:00:00.000000000 +0100
  2128. +++ uClibc/libc/sysdeps/linux/cris/vfork.S 2011-04-26 16:18:22.058385770 +0200
  2129. @@ -0,0 +1,30 @@
  2130. +/*-
  2131. + * Copyright (c) 2011
  2132. + * Thorsten Glaser <tg@freewrt.org>
  2133. + *
  2134. + * This file is available either under the terms and conditions of
  2135. + * the MirOS Licence, or the same terms as klibc or uClibc.
  2136. + */
  2137. +
  2138. +#include "sysdep.h"
  2139. +
  2140. + .syntax no_register_prefix
  2141. +
  2142. +/*
  2143. + * vfork is special, but PSEUDO() would probably work were it not broken;
  2144. + * there must be nothing at all on the stack above the stack frame of the
  2145. + * enclosing function
  2146. + */
  2147. +
  2148. +ENTRY(__vfork)
  2149. + movu.w __NR_vfork,$r9
  2150. + break 13
  2151. + cmps.w -4096,$r10
  2152. + bhs 0f
  2153. + nop
  2154. + Ret
  2155. + nop
  2156. +PSEUDO_END(__vfork)
  2157. +
  2158. +weak_alias(__vfork,vfork)
  2159. +libc_hidden_weak(vfork)
  2160. diff -Nur uClibc-0.9.32-rc3/libc/sysdeps/linux/Makefile.commonarch uClibc/libc/sysdeps/linux/Makefile.commonarch
  2161. --- uClibc-0.9.32-rc3/libc/sysdeps/linux/Makefile.commonarch 2011-03-16 20:11:13.000000000 +0100
  2162. +++ uClibc/libc/sysdeps/linux/Makefile.commonarch 2011-04-26 16:18:21.917874257 +0200
  2163. @@ -36,6 +36,6 @@
  2164. headers-y += $(ARCH_HEADERS_OUT)
  2165. headers_clean-y += HEADERCLEAN_$(subst $(top_builddir),,$(ARCH_OUT))
  2166. HEADERCLEAN_$(subst $(top_builddir),,$(ARCH_OUT)):
  2167. - $(RM) $(ARCH_HEADERS_OUT)
  2168. + $(do_rm) $(ARCH_HEADERS_OUT)
  2169. endif
  2170. diff -Nur uClibc-0.9.32-rc3/libc/sysdeps/linux/sparc/soft-fp/sfp-machine.h uClibc/libc/sysdeps/linux/sparc/soft-fp/sfp-machine.h
  2171. --- uClibc-0.9.32-rc3/libc/sysdeps/linux/sparc/soft-fp/sfp-machine.h 2011-03-16 20:11:13.000000000 +0100
  2172. +++ uClibc/libc/sysdeps/linux/sparc/soft-fp/sfp-machine.h 2011-04-26 16:18:22.198914568 +0200
  2173. @@ -187,6 +187,7 @@
  2174. #define _FP_DECL_EX fpu_control_t _fcw
  2175. +#ifdef __UCLIBC_HAS_FPU__
  2176. #define FP_INIT_ROUNDMODE \
  2177. do { \
  2178. _FPU_GETCW(_fcw); \
  2179. @@ -211,3 +212,4 @@
  2180. else \
  2181. ___Q_simulate_exceptions (_fex); \
  2182. } while (0)
  2183. +#endif
  2184. diff -Nur uClibc-0.9.32-rc3/libubacktrace/backtrace.c uClibc/libubacktrace/backtrace.c
  2185. --- uClibc-0.9.32-rc3/libubacktrace/backtrace.c 2011-03-16 20:11:13.000000000 +0100
  2186. +++ uClibc/libubacktrace/backtrace.c 2011-04-26 16:18:22.608067667 +0200
  2187. @@ -4,16 +4,81 @@
  2188. * User application that wants to use backtrace needs to be
  2189. * compiled with -fexceptions option and -rdynamic to get full
  2190. * symbols printed.
  2191. -
  2192. - * Copyright (C) 2010 STMicroelectronics Ltd
  2193. + *
  2194. + * Copyright (C) 2009, 2010 STMicroelectronics Ltd.
  2195. + *
  2196. + * Author(s): Giuseppe Cavallaro <peppe.cavallaro@st.com>
  2197. + * - Initial implementation for glibc
  2198. + *
  2199. * Author(s): Carmelo Amoroso <carmelo.amoroso@st.com>
  2200. + * - Reworked for uClibc
  2201. + * - use dlsym/dlopen from libdl
  2202. + * - rewrite initialisation to not use libc_once
  2203. + * - make it available in static link too
  2204. *
  2205. * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  2206. *
  2207. */
  2208. -#error "Arch specific implementation must be provided to properly work"
  2209. -int backtrace (void **array, int size)
  2210. +
  2211. +#include <execinfo.h>
  2212. +#include <dlfcn.h>
  2213. +#include <stdlib.h>
  2214. +#include <unwind.h>
  2215. +#include <assert.h>
  2216. +#include <stdio.h>
  2217. +
  2218. +struct trace_arg
  2219. {
  2220. - return -1;
  2221. + void **array;
  2222. + int cnt, size;
  2223. +};
  2224. +
  2225. +static _Unwind_Reason_Code (*unwind_backtrace) (_Unwind_Trace_Fn, void *);
  2226. +static _Unwind_Ptr (*unwind_getip) (struct _Unwind_Context *);
  2227. +
  2228. +static void backtrace_init (void)
  2229. +{
  2230. + void *handle = dlopen ("libgcc_s.so.1", RTLD_LAZY);
  2231. +
  2232. + if (handle == NULL
  2233. + || ((unwind_backtrace = dlsym (handle, "_Unwind_Backtrace")) == NULL)
  2234. + || ((unwind_getip = dlsym (handle, "_Unwind_GetIP")) == NULL)) {
  2235. + printf("libgcc_s.so.1 must be installed for backtrace to work\n");
  2236. + abort();
  2237. + }
  2238. }
  2239. +static _Unwind_Reason_Code
  2240. +backtrace_helper (struct _Unwind_Context *ctx, void *a)
  2241. +{
  2242. + struct trace_arg *arg = a;
  2243. +
  2244. + assert (unwind_getip != NULL);
  2245. +
  2246. + /* We are first called with address in the __backtrace function. Skip it. */
  2247. + if (arg->cnt != -1)
  2248. + arg->array[arg->cnt] = (void *) unwind_getip (ctx);
  2249. + if (++arg->cnt == arg->size)
  2250. + return _URC_END_OF_STACK;
  2251. + return _URC_NO_REASON;
  2252. +}
  2253. +
  2254. +/*
  2255. + * Perform stack unwinding by using the _Unwind_Backtrace.
  2256. + *
  2257. + * User application that wants to use backtrace needs to be
  2258. + * compiled with -fexceptions option and -rdynamic to get full
  2259. + * symbols printed.
  2260. + */
  2261. +int backtrace (void **array, int size)
  2262. +{
  2263. + struct trace_arg arg = { .array = array, .size = size, .cnt = -1 };
  2264. +
  2265. + if (unwind_backtrace == NULL)
  2266. + backtrace_init();
  2267. +
  2268. + if (size >= 1)
  2269. + unwind_backtrace (backtrace_helper, &arg);
  2270. +
  2271. + return arg.cnt != -1 ? arg.cnt : 0;
  2272. +}
  2273. diff -Nur uClibc-0.9.32-rc3/libubacktrace/Makefile.in uClibc/libubacktrace/Makefile.in
  2274. --- uClibc-0.9.32-rc3/libubacktrace/Makefile.in 2011-03-16 20:11:13.000000000 +0100
  2275. +++ uClibc/libubacktrace/Makefile.in 2011-04-26 16:18:22.608067667 +0200
  2276. @@ -18,29 +18,16 @@
  2277. libubacktrace_DIR := $(top_srcdir)libubacktrace
  2278. libubacktrace_OUT := $(top_builddir)libubacktrace
  2279. -libubacktrace_ARCH_DIR := $(libubacktrace_DIR)/sysdeps/$(TARGET_ARCH)
  2280. -libubacktrace_ARCH_OUT := $(libubacktrace_OUT)/sysdeps/$(TARGET_ARCH)
  2281. -
  2282. --include $(libubacktrace_ARCH_DIR)/Makefile.arch
  2283. libubacktrace_SRC-y :=
  2284. libubacktrace_SRC-$(UCLIBC_HAS_BACKTRACE) := backtrace.c backtracesyms.c backtracesymsfd.c
  2285. -CFLAGS-libubacktrace/sysdeps/$(TARGET_ARCH)/ := $(CFLAGS-libubacktrace)
  2286. -
  2287. -# remove generic sources, if arch specific version is present
  2288. -ifneq ($(strip $(libubacktrace_ARCH_SRC-y)),)
  2289. -libubacktrace_SRC-y := $(filter-out $(notdir $(libubacktrace_ARCH_SRC-y)),$(libubacktrace_SRC-y))
  2290. -libubacktrace_ARCH_SRC := $(addprefix $(libubacktrace_ARCH_DIR)/,$(libubacktrace_ARCH_SRC-y))
  2291. -libubacktrace_ARCH_OBJ := $(patsubst $(libubacktrace_ARCH_DIR)/%.c,$(libubacktrace_ARCH_OUT)/%.o,$(libubacktrace_ARCH_SRC))
  2292. -endif
  2293. -
  2294. +# -fexections is required for backtrace to work using dwarf2
  2295. +CFLAGS-backtrace.c := -fexceptions
  2296. -libubacktrace_SRC := $(addprefix $(libubacktrace_DIR)/,$(libubacktrace_SRC-y))
  2297. -libubacktrace_OBJ := $(patsubst $(libubacktrace_DIR)/%.c,$(libubacktrace_OUT)/%.o,$(libubacktrace_SRC))
  2298. -libubacktrace_SRCS := $(libubacktrace_SRC) $(libubacktrace_ARCH_SRC)
  2299. -libubacktrace_OBJS := $(libubacktrace_OBJ) $(libubacktrace_ARCH_OBJ)
  2300. +libubacktrace_SRCS := $(addprefix $(libubacktrace_DIR)/,$(libubacktrace_SRC-y))
  2301. +libubacktrace_OBJS := $(patsubst $(libubacktrace_DIR)/%.c,$(libubacktrace_OUT)/%.o,$(libubacktrace_SRCS))
  2302. ifeq ($(DOPIC),y)
  2303. libubacktrace-a-y := $(libubacktrace_OBJS:.o=.os)
  2304. diff -Nur uClibc-0.9.32-rc3/libubacktrace/sysdeps/sh/backtrace.c uClibc/libubacktrace/sysdeps/sh/backtrace.c
  2305. --- uClibc-0.9.32-rc3/libubacktrace/sysdeps/sh/backtrace.c 2011-03-16 20:11:13.000000000 +0100
  2306. +++ uClibc/libubacktrace/sysdeps/sh/backtrace.c 1970-01-01 01:00:00.000000000 +0100
  2307. @@ -1,84 +0,0 @@
  2308. -/*
  2309. - * Perform stack unwinding by using the _Unwind_Backtrace.
  2310. - *
  2311. - * User application that wants to use backtrace needs to be
  2312. - * compiled with -fexceptions option and -rdynamic to get full
  2313. - * symbols printed.
  2314. - *
  2315. - * Copyright (C) 2009, 2010 STMicroelectronics Ltd.
  2316. - *
  2317. - * Author(s): Giuseppe Cavallaro <peppe.cavallaro@st.com>
  2318. - * - Initial implementation for glibc
  2319. - *
  2320. - * Author(s): Carmelo Amoroso <carmelo.amoroso@st.com>
  2321. - * - Reworked for uClibc
  2322. - * - use dlsym/dlopen from libdl
  2323. - * - rewrite initialisation to not use libc_once
  2324. - * - make it available in static link too
  2325. - *
  2326. - * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  2327. - *
  2328. - */
  2329. -
  2330. -#include <execinfo.h>
  2331. -#include <dlfcn.h>
  2332. -#include <stdlib.h>
  2333. -#include <unwind.h>
  2334. -#include <assert.h>
  2335. -#include <stdio.h>
  2336. -
  2337. -struct trace_arg
  2338. -{
  2339. - void **array;
  2340. - int cnt, size;
  2341. -};
  2342. -
  2343. -static _Unwind_Reason_Code (*unwind_backtrace) (_Unwind_Trace_Fn, void *);
  2344. -static _Unwind_Ptr (*unwind_getip) (struct _Unwind_Context *);
  2345. -
  2346. -static void backtrace_init (void)
  2347. -{
  2348. - void *handle = dlopen ("libgcc_s.so.1", RTLD_LAZY);
  2349. -
  2350. - if (handle == NULL
  2351. - || ((unwind_backtrace = dlsym (handle, "_Unwind_Backtrace")) == NULL)
  2352. - || ((unwind_getip = dlsym (handle, "_Unwind_GetIP")) == NULL)) {
  2353. - printf("libgcc_s.so.1 must be installed for backtrace to work\n");
  2354. - abort();
  2355. - }
  2356. -}
  2357. -
  2358. -static _Unwind_Reason_Code
  2359. -backtrace_helper (struct _Unwind_Context *ctx, void *a)
  2360. -{
  2361. - struct trace_arg *arg = a;
  2362. -
  2363. - assert (unwind_getip != NULL);
  2364. -
  2365. - /* We are first called with address in the __backtrace function. Skip it. */
  2366. - if (arg->cnt != -1)
  2367. - arg->array[arg->cnt] = (void *) unwind_getip (ctx);
  2368. - if (++arg->cnt == arg->size)
  2369. - return _URC_END_OF_STACK;
  2370. - return _URC_NO_REASON;
  2371. -}
  2372. -
  2373. -/*
  2374. - * Perform stack unwinding by using the _Unwind_Backtrace.
  2375. - *
  2376. - * User application that wants to use backtrace needs to be
  2377. - * compiled with -fexceptions option and -rdynamic to get full
  2378. - * symbols printed.
  2379. - */
  2380. -int backtrace (void **array, int size)
  2381. -{
  2382. - struct trace_arg arg = { .array = array, .size = size, .cnt = -1 };
  2383. -
  2384. - if (unwind_backtrace == NULL)
  2385. - backtrace_init();
  2386. -
  2387. - if (size >= 1)
  2388. - unwind_backtrace (backtrace_helper, &arg);
  2389. -
  2390. - return arg.cnt != -1 ? arg.cnt : 0;
  2391. -}
  2392. diff -Nur uClibc-0.9.32-rc3/libubacktrace/sysdeps/sh/Makefile.arch uClibc/libubacktrace/sysdeps/sh/Makefile.arch
  2393. --- uClibc-0.9.32-rc3/libubacktrace/sysdeps/sh/Makefile.arch 2011-03-16 20:11:13.000000000 +0100
  2394. +++ uClibc/libubacktrace/sysdeps/sh/Makefile.arch 1970-01-01 01:00:00.000000000 +0100
  2395. @@ -1,12 +0,0 @@
  2396. -# Makefile for uClibc (sh/libubacktrace)
  2397. -#
  2398. -# Copyright (C) 2010 STMicroelectronics Ltd
  2399. -# Author: Carmelo Amoroso <carmelo.amoroso@st.com>
  2400. -
  2401. -# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  2402. -#
  2403. -
  2404. -libubacktrace_ARCH_SRC-y := backtrace.c
  2405. -
  2406. -# -fexections is required for backtrace to work using dwarf2
  2407. -CFLAGS-backtrace.c := -fexceptions
  2408. diff -Nur uClibc-0.9.32-rc3/Makefile.in uClibc/Makefile.in
  2409. --- uClibc-0.9.32-rc3/Makefile.in 2011-03-16 20:11:13.000000000 +0100
  2410. +++ uClibc/Makefile.in 2011-04-26 16:18:21.697662740 +0200
  2411. @@ -239,6 +239,7 @@
  2412. tgmath.h \
  2413. bits/math*.h
  2414. HEADERS_RM-$(findstring y,$(UCLIBC_HAS_FTW)$(UCLIBC_HAS_NFTW)) += ftw.h
  2415. +HEADERS_RM-$(UCLIBC_HAS_FTS) += fts.h
  2416. HEADERS_RM-$(UCLIBC_HAS_GETTEXT_AWARENESS) += libintl.h
  2417. HEADERS_RM-$(UCLIBC_HAS_GLIBC_CUSTOM_PRINTF) += printf.h
  2418. HEADERS_RM-$(UCLIBC_HAS_GLOB) += glob.h
  2419. diff -Nur uClibc-0.9.32-rc3/Rules.mak uClibc/Rules.mak
  2420. --- uClibc-0.9.32-rc3/Rules.mak 2011-03-16 20:11:13.000000000 +0100
  2421. +++ uClibc/Rules.mak 2011-04-26 16:18:21.697662740 +0200
  2422. @@ -531,7 +531,7 @@
  2423. export CC_FLAG_NO_ASNEEDED:=-Wl,$(LD_FLAG_NO_ASNEEDED)
  2424. endif
  2425. endif
  2426. -link.asneeded = $(if $(and $(CC_FLAG_ASNEEDED),$(CC_FLAG_NO_ASNEEDED)),$(CC_FLAG_ASNEEDED) $(1) $(CC_FLAG_NO_ASNEEDED))
  2427. +link.asneeded = $(if $(findstring yy,$(CC_FLAG_ASNEEDED)$(CC_FLAG_NO_ASNEEDED)),$(CC_FLAG_ASNEEDED) $(1) $(CC_FLAG_NO_ASNEEDED))
  2428. # Check for AS_NEEDED support in linker script (binutils>=2.16.1 has it)
  2429. ifndef ASNEEDED
  2430. diff -Nur uClibc-0.9.32-rc3/test/tls/Makefile.in uClibc/test/tls/Makefile.in
  2431. --- uClibc-0.9.32-rc3/test/tls/Makefile.in 2011-03-16 20:11:13.000000000 +0100
  2432. +++ uClibc/test/tls/Makefile.in 2011-04-26 16:18:22.827742938 +0200
  2433. @@ -140,7 +140,6 @@
  2434. $(LDFLAGS_tst-tlsmod18a.so)
  2435. tst-tls-at-ctor: tst-tlsmod-at-ctor.so
  2436. -RET_tst-tls13 := 1
  2437. ifeq ($(TARGET_ARCH),mips)
  2438. RET_tst-tls15 := 1
  2439. endif
  2440. diff -Nur uClibc-0.9.32-rc3/test/tls/tst-tls13.c uClibc/test/tls/tst-tls13.c
  2441. --- uClibc-0.9.32-rc3/test/tls/tst-tls13.c 2011-03-16 20:11:13.000000000 +0100
  2442. +++ uClibc/test/tls/tst-tls13.c 2011-04-26 16:18:22.837818558 +0200
  2443. @@ -26,5 +26,5 @@
  2444. }
  2445. #define TEST_FUNCTION do_test ()
  2446. -#define TIMEOUT 3
  2447. +#define TIMEOUT 20
  2448. #include "../test-skeleton.c"
  2449. diff -Nur uClibc-0.9.32-rc3/utils/ldd.c uClibc/utils/ldd.c
  2450. --- uClibc-0.9.32-rc3/utils/ldd.c 2011-03-16 20:11:13.000000000 +0100
  2451. +++ uClibc/utils/ldd.c 2011-04-26 16:18:22.888166105 +0200
  2452. @@ -553,7 +553,7 @@
  2453. interp_name = strdup(s);
  2454. interp_dir = strdup(s);
  2455. tmp = strrchr(interp_dir, '/');
  2456. - if (*tmp)
  2457. + if (tmp)
  2458. *tmp = '\0';
  2459. else {
  2460. free(interp_dir);