1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506 |
- diff -Nur uClibc-0.9.32-rc3/extra/Configs/Config.in uClibc/extra/Configs/Config.in
- --- uClibc-0.9.32-rc3/extra/Configs/Config.in 2011-03-16 20:11:13.000000000 +0100
- +++ uClibc/extra/Configs/Config.in 2011-04-26 16:18:21.707661578 +0200
- @@ -1898,6 +1898,18 @@
- This interface is rarely used, and adds around 4.5k. Unless you have
- a pressing need for ftw(), you should probably answer N.
-
- +config UCLIBC_HAS_FTS
- + bool "Support the fts() interface (bsd-compat)"
- + default n
- + help
- + The fts functions are provided for traversing UNIX file hierarchies.
- +
- + This interface is currently used by the elfutils and adds
- + around 7.5k.
- + You should port your application to use the POSIX nftw()
- + interface.
- +
- + Unless you need to build/use elfutils, you should prolly answer N.
-
- config UCLIBC_HAS_GLOB
- bool "Support the glob() interface"
- @@ -2322,7 +2334,7 @@
-
- config UCLIBC_HAS_BACKTRACE
- bool "Add support for application self-debugging"
- - depends on HAVE_SHARED && TARGET_sh
- + depends on HAVE_SHARED
- default n
- help
- Answer Y here to compile support for application self-debugging, by adding
- diff -Nur uClibc-0.9.32-rc3/include/fts.h uClibc/include/fts.h
- --- uClibc-0.9.32-rc3/include/fts.h 1970-01-01 01:00:00.000000000 +0100
- +++ uClibc/include/fts.h 2011-04-26 16:18:21.727663221 +0200
- @@ -0,0 +1,131 @@
- +/*
- + * Copyright (c) 1989, 1993
- + * The Regents of the University of California. All rights reserved.
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions
- + * are met:
- + * 1. Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * 2. Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * 4. Neither the name of the University nor the names of its contributors
- + * may be used to endorse or promote products derived from this software
- + * without specific prior written permission.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- + * SUCH DAMAGE.
- + *
- + * @(#)fts.h 8.3 (Berkeley) 8/14/94
- + */
- +
- +#ifndef _FTS_H
- +#define _FTS_H 1
- +
- +#include <features.h>
- +#include <sys/types.h>
- +
- +/* The fts interface is incompatible with the LFS interface which
- + transparently uses the 64-bit file access functions. */
- +#ifdef __USE_FILE_OFFSET64
- +# error "<fts.h> cannot be used with -D_FILE_OFFSET_BITS==64"
- +#endif
- +
- +
- +typedef struct {
- + struct _ftsent *fts_cur; /* current node */
- + struct _ftsent *fts_child; /* linked list of children */
- + struct _ftsent **fts_array; /* sort array */
- + dev_t fts_dev; /* starting device # */
- + char *fts_path; /* path for this descent */
- + int fts_rfd; /* fd for root */
- + int fts_pathlen; /* sizeof(path) */
- + int fts_nitems; /* elements in the sort array */
- + int (*fts_compar) (const void *, const void *); /* compare fn */
- +
- +#define FTS_COMFOLLOW 0x0001 /* follow command line symlinks */
- +#define FTS_LOGICAL 0x0002 /* logical walk */
- +#define FTS_NOCHDIR 0x0004 /* don't change directories */
- +#define FTS_NOSTAT 0x0008 /* don't get stat info */
- +#define FTS_PHYSICAL 0x0010 /* physical walk */
- +#define FTS_SEEDOT 0x0020 /* return dot and dot-dot */
- +#define FTS_XDEV 0x0040 /* don't cross devices */
- +#define FTS_WHITEOUT 0x0080 /* return whiteout information */
- +#define FTS_OPTIONMASK 0x00ff /* valid user option mask */
- +
- +#define FTS_NAMEONLY 0x0100 /* (private) child names only */
- +#define FTS_STOP 0x0200 /* (private) unrecoverable error */
- + int fts_options; /* fts_open options, global flags */
- +} FTS;
- +
- +typedef struct _ftsent {
- + struct _ftsent *fts_cycle; /* cycle node */
- + struct _ftsent *fts_parent; /* parent directory */
- + struct _ftsent *fts_link; /* next file in directory */
- + long fts_number; /* local numeric value */
- + void *fts_pointer; /* local address value */
- + char *fts_accpath; /* access path */
- + char *fts_path; /* root path */
- + int fts_errno; /* errno for this node */
- + int fts_symfd; /* fd for symlink */
- + u_short fts_pathlen; /* strlen(fts_path) */
- + u_short fts_namelen; /* strlen(fts_name) */
- +
- + ino_t fts_ino; /* inode */
- + dev_t fts_dev; /* device */
- + nlink_t fts_nlink; /* link count */
- +
- +#define FTS_ROOTPARENTLEVEL -1
- +#define FTS_ROOTLEVEL 0
- + short fts_level; /* depth (-1 to N) */
- +
- +#define FTS_D 1 /* preorder directory */
- +#define FTS_DC 2 /* directory that causes cycles */
- +#define FTS_DEFAULT 3 /* none of the above */
- +#define FTS_DNR 4 /* unreadable directory */
- +#define FTS_DOT 5 /* dot or dot-dot */
- +#define FTS_DP 6 /* postorder directory */
- +#define FTS_ERR 7 /* error; errno is set */
- +#define FTS_F 8 /* regular file */
- +#define FTS_INIT 9 /* initialized only */
- +#define FTS_NS 10 /* stat(2) failed */
- +#define FTS_NSOK 11 /* no stat(2) requested */
- +#define FTS_SL 12 /* symbolic link */
- +#define FTS_SLNONE 13 /* symbolic link without target */
- +#define FTS_W 14 /* whiteout object */
- + u_short fts_info; /* user flags for FTSENT structure */
- +
- +#define FTS_DONTCHDIR 0x01 /* don't chdir .. to the parent */
- +#define FTS_SYMFOLLOW 0x02 /* followed a symlink to get here */
- + u_short fts_flags; /* private flags for FTSENT structure */
- +
- +#define FTS_AGAIN 1 /* read node again */
- +#define FTS_FOLLOW 2 /* follow symbolic link */
- +#define FTS_NOINSTR 3 /* no instructions */
- +#define FTS_SKIP 4 /* discard node */
- + u_short fts_instr; /* fts_set() instructions */
- +
- + struct stat *fts_statp; /* stat(2) information */
- + char fts_name[1]; /* file name */
- +} FTSENT;
- +
- +__BEGIN_DECLS
- +FTSENT *fts_children (FTS *, int);
- +int fts_close (FTS *);
- +FTS *fts_open (char * const *, int,
- + int (*)(const FTSENT **, const FTSENT **));
- +FTSENT *fts_read (FTS *);
- +int fts_set (FTS *, FTSENT *, int) __THROW;
- +__END_DECLS
- +
- +#endif /* fts.h */
- diff -Nur uClibc-0.9.32-rc3/ldso/include/dl-elf.h uClibc/ldso/include/dl-elf.h
- --- uClibc-0.9.32-rc3/ldso/include/dl-elf.h 2011-03-16 20:11:13.000000000 +0100
- +++ uClibc/ldso/include/dl-elf.h 2011-04-26 16:18:21.747664948 +0200
- @@ -184,7 +184,7 @@
- ADJUST_DYN_INFO(DT_DSBT_BASE_IDX, load_off);
-
- /* Initialize loadmap dsbt info. */
- - load_off.map->dsbt_table = dynamic_info[DT_DSBT_BASE_IDX];
- + load_off.map->dsbt_table = (void *)dynamic_info[DT_DSBT_BASE_IDX];
- load_off.map->dsbt_size = dynamic_info[DT_DSBT_SIZE_IDX];
- load_off.map->dsbt_index = dynamic_info[DT_DSBT_INDEX_IDX];
- #endif
- diff -Nur uClibc-0.9.32-rc3/ldso/include/ldso.h uClibc/ldso/include/ldso.h
- --- uClibc-0.9.32-rc3/ldso/include/ldso.h 2011-03-16 20:11:13.000000000 +0100
- +++ uClibc/ldso/include/ldso.h 2011-04-26 16:18:21.747664948 +0200
- @@ -34,6 +34,8 @@
- #include <sys/types.h>
- /* Pull in the arch specific page size */
- #include <bits/uClibc_page.h>
- +/* Pull in the MIN macro */
- +#include <sys/param.h>
- /* Pull in the ldso syscalls and string functions */
- #ifndef __ARCH_HAS_NO_SHARED__
- #include <dl-syscall.h>
- diff -Nur uClibc-0.9.32-rc3/ldso/ldso/bfin/dl-inlines.h uClibc/ldso/ldso/bfin/dl-inlines.h
- --- uClibc-0.9.32-rc3/ldso/ldso/bfin/dl-inlines.h 2011-03-16 20:11:13.000000000 +0100
- +++ uClibc/ldso/ldso/bfin/dl-inlines.h 2011-04-26 16:18:21.747664948 +0200
- @@ -88,14 +88,39 @@
- segdata->p_memsz = phdr->p_memsz;
-
- #if defined (__SUPPORT_LD_DEBUG__)
- - {
- - extern char *_dl_debug;
- - extern int _dl_debug_file;
- - if (_dl_debug)
- - _dl_dprintf(_dl_debug_file, "%i: mapped %x at %x, size %x\n",
- - loadaddr.map->nsegs-1,
- - segdata->p_vaddr, segdata->addr, segdata->p_memsz);
- - }
- + if (_dl_debug)
- + _dl_dprintf(_dl_debug_file, "%i: mapped %x at %x, size %x\n",
- + loadaddr.map->nsegs-1,
- + segdata->p_vaddr, segdata->addr, segdata->p_memsz);
- +#endif
- +}
- +
- +/* Replace an existing entry in the load map. */
- +static __always_inline void
- +__dl_update_loadaddr_hdr (struct elf32_fdpic_loadaddr loadaddr, void *addr,
- + Elf32_Phdr *phdr)
- +{
- + struct elf32_fdpic_loadseg *segdata;
- + void *oldaddr;
- + int i;
- +
- + for (i = 0; i < loadaddr.map->nsegs; i++)
- + if (loadaddr.map->segs[i].p_vaddr == phdr->p_vaddr
- + && loadaddr.map->segs[i].p_memsz == phdr->p_memsz)
- + break;
- + if (i == loadaddr.map->nsegs)
- + _dl_exit (-1);
- +
- + segdata = loadaddr.map->segs + i;
- + oldaddr = (void *)segdata->addr;
- + _dl_munmap (oldaddr, segdata->p_memsz);
- + segdata->addr = (Elf32_Addr) addr;
- +
- +#if defined (__SUPPORT_LD_DEBUG__)
- + if (_dl_debug)
- + _dl_dprintf(_dl_debug_file, "%i: changed mapping %x at %x (old %x), size %x\n",
- + loadaddr.map->nsegs-1,
- + segdata->p_vaddr, segdata->addr, oldaddr, segdata->p_memsz);
- #endif
- }
-
- diff -Nur uClibc-0.9.32-rc3/ldso/ldso/bfin/dl-sysdep.h uClibc/ldso/ldso/bfin/dl-sysdep.h
- --- uClibc-0.9.32-rc3/ldso/ldso/bfin/dl-sysdep.h 2011-03-16 20:11:13.000000000 +0100
- +++ uClibc/ldso/ldso/bfin/dl-sysdep.h 2011-04-26 16:18:21.747664948 +0200
- @@ -120,6 +120,8 @@
- #define DL_INIT_LOADADDR_HDR(LOADADDR, ADDR, PHDR) \
- (__dl_init_loadaddr_hdr ((LOADADDR), (ADDR), (PHDR), \
- dl_init_loadaddr_load_count))
- +#define DL_UPDATE_LOADADDR_HDR(LOADADDR, ADDR, PHDR) \
- + (__dl_update_loadaddr_hdr ((LOADADDR), (ADDR), (PHDR)))
- #define DL_LOADADDR_UNMAP(LOADADDR, LEN) \
- (__dl_loadaddr_unmap ((LOADADDR), (NULL)))
- #define DL_LIB_UNMAP(LIB, LEN) \
- diff -Nur uClibc-0.9.32-rc3/ldso/ldso/c6x/dl-inlines.h uClibc/ldso/ldso/c6x/dl-inlines.h
- --- uClibc-0.9.32-rc3/ldso/ldso/c6x/dl-inlines.h 2011-03-16 20:11:13.000000000 +0100
- +++ uClibc/ldso/ldso/c6x/dl-inlines.h 2011-04-26 16:18:21.747664948 +0200
- @@ -74,6 +74,35 @@
- #endif
- }
-
- +/* Replace an existing entry in the load map. */
- +static __always_inline void
- +__dl_update_loadaddr_hdr (struct elf32_dsbt_loadaddr loadaddr, void *addr,
- + Elf32_Phdr *phdr)
- +{
- + struct elf32_dsbt_loadseg *segdata;
- + void *oldaddr;
- + int i;
- +
- + for (i = 0; i < loadaddr.map->nsegs; i++)
- + if (loadaddr.map->segs[i].p_vaddr == phdr->p_vaddr
- + && loadaddr.map->segs[i].p_memsz == phdr->p_memsz)
- + break;
- + if (i == loadaddr.map->nsegs)
- + _dl_exit (-1);
- +
- + segdata = loadaddr.map->segs + i;
- + oldaddr = (void *)segdata->addr;
- + _dl_munmap (oldaddr, segdata->p_memsz);
- + segdata->addr = (Elf32_Addr) addr;
- +
- +#if defined (__SUPPORT_LD_DEBUG__)
- + if (_dl_debug)
- + _dl_dprintf(_dl_debug_file, "%i: changed mapping %x at %x (old %x), size %x\n",
- + loadaddr.map->nsegs-1,
- + segdata->p_vaddr, segdata->addr, oldaddr, segdata->p_memsz);
- +#endif
- +}
- +
- static __always_inline void
- __dl_loadaddr_unmap (struct elf32_dsbt_loadaddr loadaddr)
- {
- diff -Nur uClibc-0.9.32-rc3/ldso/ldso/c6x/dl-sysdep.h uClibc/ldso/ldso/c6x/dl-sysdep.h
- --- uClibc-0.9.32-rc3/ldso/ldso/c6x/dl-sysdep.h 2011-03-16 20:11:13.000000000 +0100
- +++ uClibc/ldso/ldso/c6x/dl-sysdep.h 2011-04-26 16:18:21.747664948 +0200
- @@ -104,6 +104,9 @@
- (__dl_init_loadaddr_hdr ((LOADADDR), (ADDR), (PHDR), \
- dl_init_loadaddr_load_count))
-
- +#define DL_UPDATE_LOADADDR_HDR(LOADADDR, ADDR, PHDR) \
- + (__dl_update_loadaddr_hdr ((LOADADDR), (ADDR), (PHDR)))
- +
- #define DL_LOADADDR_UNMAP(LOADADDR, LEN) \
- (__dl_loadaddr_unmap ((LOADADDR)))
-
- diff -Nur uClibc-0.9.32-rc3/ldso/ldso/c6x/elfinterp.c uClibc/ldso/ldso/c6x/elfinterp.c
- --- uClibc-0.9.32-rc3/ldso/ldso/c6x/elfinterp.c 2011-03-16 20:11:13.000000000 +0100
- +++ uClibc/ldso/ldso/c6x/elfinterp.c 2011-04-26 16:18:21.747664948 +0200
- @@ -198,6 +198,10 @@
- new_val = sym_val;
- *reloc_addr = sym_val;
- break;
- + case R_C6000_DSBT_INDEX:
- + new_val = (old_val & ~0x007fff00) | ((tpnt->loadaddr.map->dsbt_index & 0x7fff) << 8);
- + *reloc_addr = new_val;
- + break;
- case R_C6000_ABS_L16:
- new_val = (old_val & ~0x007fff80) | ((sym_val & 0xffff) << 7);
- *reloc_addr = new_val;
- @@ -224,7 +228,7 @@
- (char *)symbol_addr,
- symtab[symtab_index].st_size);
- }
- - break;
- + return 0;
- default:
- return -1; /*call _dl_exit(1) */
- }
- diff -Nur uClibc-0.9.32-rc3/ldso/ldso/dl-elf.c uClibc/ldso/ldso/dl-elf.c
- --- uClibc-0.9.32-rc3/ldso/ldso/dl-elf.c 2011-03-16 20:11:13.000000000 +0100
- +++ uClibc/ldso/ldso/dl-elf.c 2011-04-26 16:18:21.747664948 +0200
- @@ -314,6 +314,121 @@
- return NULL;
- }
-
- +/*
- + * Make a writeable mapping of a segment, regardless of whether PF_W is
- + * set or not.
- + */
- +static void *
- +map_writeable (int infile, ElfW(Phdr) *ppnt, int piclib, int flags,
- + unsigned long libaddr)
- +{
- + int prot_flags = ppnt->p_flags | PF_W;
- + char *status, *retval;
- + char *tryaddr;
- + ssize_t size;
- + unsigned long map_size;
- + char *cpnt;
- + char *piclib2map = NULL;
- +
- + if (piclib == 2 &&
- + /* We might be able to avoid this call if memsz doesn't
- + require an additional page, but this would require mmap
- + to always return page-aligned addresses and a whole
- + number of pages allocated. Unfortunately on uClinux
- + may return misaligned addresses and may allocate
- + partial pages, so we may end up doing unnecessary mmap
- + calls.
- +
- + This is what we could do if we knew mmap would always
- + return aligned pages:
- +
- + ((ppnt->p_vaddr + ppnt->p_filesz + ADDR_ALIGN) &
- + PAGE_ALIGN) < ppnt->p_vaddr + ppnt->p_memsz)
- +
- + Instead, we have to do this: */
- + ppnt->p_filesz < ppnt->p_memsz)
- + {
- + piclib2map = (char *)
- + _dl_mmap(0, (ppnt->p_vaddr & ADDR_ALIGN) + ppnt->p_memsz,
- + LXFLAGS(prot_flags), flags | MAP_ANONYMOUS, -1, 0);
- + if (_dl_mmap_check_error(piclib2map))
- + return 0;
- + }
- +
- + tryaddr = piclib == 2 ? piclib2map
- + : ((char*) (piclib ? libaddr : 0) +
- + (ppnt->p_vaddr & PAGE_ALIGN));
- +
- + size = (ppnt->p_vaddr & ADDR_ALIGN) + ppnt->p_filesz;
- +
- + /* For !MMU, mmap to fixed address will fail.
- + So instead of desperately call mmap and fail,
- + we set status to MAP_FAILED to save a call
- + to mmap (). */
- +#ifndef __ARCH_USE_MMU__
- + if (piclib2map == 0)
- +#endif
- + status = (char *) _dl_mmap
- + (tryaddr, size, LXFLAGS(prot_flags),
- + flags | (piclib2map ? MAP_FIXED : 0),
- + infile, ppnt->p_offset & OFFS_ALIGN);
- +#ifndef __ARCH_USE_MMU__
- + else
- + status = MAP_FAILED;
- +#endif
- +#ifdef _DL_PREAD
- + if (_dl_mmap_check_error(status) && piclib2map
- + && (_DL_PREAD (infile, tryaddr, size,
- + ppnt->p_offset & OFFS_ALIGN) == size))
- + status = tryaddr;
- +#endif
- + if (_dl_mmap_check_error(status) || (tryaddr && tryaddr != status))
- + return 0;
- +
- + if (piclib2map)
- + retval = piclib2map;
- + else
- + retval = status;
- +
- + /* Now we want to allocate and zero-out any data from the end
- + of the region we mapped in from the file (filesz) to the
- + end of the loadable segment (memsz). We may need
- + additional pages for memsz, that we map in below, and we
- + can count on the kernel to zero them out, but we have to
- + zero out stuff in the last page that we mapped in from the
- + file. However, we can't assume to have actually obtained
- + full pages from the kernel, since we didn't ask for them,
- + and uClibc may not give us full pages for small
- + allocations. So only zero out up to memsz or the end of
- + the page, whichever comes first. */
- +
- + /* CPNT is the beginning of the memsz portion not backed by
- + filesz. */
- + cpnt = (char *) (status + size);
- +
- + /* MAP_SIZE is the address of the
- + beginning of the next page. */
- + map_size = (ppnt->p_vaddr + ppnt->p_filesz
- + + ADDR_ALIGN) & PAGE_ALIGN;
- +
- + _dl_memset (cpnt, 0,
- + MIN (map_size
- + - (ppnt->p_vaddr
- + + ppnt->p_filesz),
- + ppnt->p_memsz
- + - ppnt->p_filesz));
- +
- + if (map_size < ppnt->p_vaddr + ppnt->p_memsz && !piclib2map) {
- + tryaddr = map_size + (char*)(piclib ? libaddr : 0);
- + status = (char *) _dl_mmap(tryaddr,
- + ppnt->p_vaddr + ppnt->p_memsz - map_size,
- + LXFLAGS(prot_flags),
- + flags | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
- + if (_dl_mmap_check_error(status) || tryaddr != status)
- + return NULL;
- + }
- + return retval;
- +}
-
- /*
- * Read one ELF library into memory, mmap it into the correct locations and
- @@ -475,6 +590,7 @@
- status = (char *) _dl_mmap((char *) (piclib ? 0 : minvma),
- maxvma - minvma, PROT_NONE, flags | MAP_ANONYMOUS, -1, 0);
- if (_dl_mmap_check_error(status)) {
- + cant_map:
- _dl_dprintf(2, "%s:%i: can't map '%s'\n", _dl_progname, __LINE__, libname);
- _dl_internal_error_number = LD_ERROR_MMAP_FAILED;
- _dl_close(infile);
- @@ -495,8 +611,11 @@
- char *addr;
-
- addr = DL_MAP_SEGMENT (epnt, ppnt, infile, flags);
- - if (addr == NULL)
- + if (addr == NULL) {
- + cant_map1:
- + DL_LOADADDR_UNMAP (lib_loadaddr, maxvma - minvma);
- goto cant_map;
- + }
-
- DL_INIT_LOADADDR_HDR (lib_loadaddr, addr, ppnt);
- ppnt++;
- @@ -517,141 +636,9 @@
- }
-
- if (ppnt->p_flags & PF_W) {
- - unsigned long map_size;
- - char *cpnt;
- - char *piclib2map = 0;
- -
- - if (piclib == 2 &&
- - /* We might be able to avoid this
- - call if memsz doesn't require
- - an additional page, but this
- - would require mmap to always
- - return page-aligned addresses
- - and a whole number of pages
- - allocated. Unfortunately on
- - uClinux may return misaligned
- - addresses and may allocate
- - partial pages, so we may end up
- - doing unnecessary mmap calls.
- -
- - This is what we could do if we
- - knew mmap would always return
- - aligned pages:
- -
- - ((ppnt->p_vaddr + ppnt->p_filesz
- - + ADDR_ALIGN)
- - & PAGE_ALIGN)
- - < ppnt->p_vaddr + ppnt->p_memsz)
- -
- - Instead, we have to do this: */
- - ppnt->p_filesz < ppnt->p_memsz)
- - {
- - piclib2map = (char *)
- - _dl_mmap(0, (ppnt->p_vaddr & ADDR_ALIGN)
- - + ppnt->p_memsz,
- - LXFLAGS(ppnt->p_flags),
- - flags | MAP_ANONYMOUS, -1, 0);
- - if (_dl_mmap_check_error(piclib2map))
- - goto cant_map;
- - DL_INIT_LOADADDR_HDR
- - (lib_loadaddr, piclib2map
- - + (ppnt->p_vaddr & ADDR_ALIGN), ppnt);
- - }
- -
- - tryaddr = piclib == 2 ? piclib2map
- - : ((char*) (piclib ? libaddr : 0) +
- - (ppnt->p_vaddr & PAGE_ALIGN));
- -
- - size = (ppnt->p_vaddr & ADDR_ALIGN)
- - + ppnt->p_filesz;
- -
- - /* For !MMU, mmap to fixed address will fail.
- - So instead of desperately call mmap and fail,
- - we set status to MAP_FAILED to save a call
- - to mmap (). */
- -#ifndef __ARCH_USE_MMU__
- - if (piclib2map == 0)
- -#endif
- - status = (char *) _dl_mmap
- - (tryaddr, size, LXFLAGS(ppnt->p_flags),
- - flags | (piclib2map ? MAP_FIXED : 0),
- - infile, ppnt->p_offset & OFFS_ALIGN);
- -#ifndef __ARCH_USE_MMU__
- - else
- - status = MAP_FAILED;
- -#endif
- -#ifdef _DL_PREAD
- - if (_dl_mmap_check_error(status) && piclib2map
- - && (_DL_PREAD (infile, tryaddr, size,
- - ppnt->p_offset & OFFS_ALIGN)
- - == size))
- - status = tryaddr;
- -#endif
- - if (_dl_mmap_check_error(status)
- - || (tryaddr && tryaddr != status)) {
- - cant_map:
- - _dl_dprintf(2, "%s:%i: can't map '%s'\n",
- - _dl_progname, __LINE__, libname);
- - _dl_internal_error_number = LD_ERROR_MMAP_FAILED;
- - DL_LOADADDR_UNMAP (lib_loadaddr, maxvma - minvma);
- - _dl_close(infile);
- - _dl_munmap(header, _dl_pagesize);
- - return NULL;
- - }
- -
- - if (! piclib2map) {
- - DL_INIT_LOADADDR_HDR
- - (lib_loadaddr, status
- - + (ppnt->p_vaddr & ADDR_ALIGN), ppnt);
- - }
- - /* Now we want to allocate and
- - zero-out any data from the end of
- - the region we mapped in from the
- - file (filesz) to the end of the
- - loadable segment (memsz). We may
- - need additional pages for memsz,
- - that we map in below, and we can
- - count on the kernel to zero them
- - out, but we have to zero out stuff
- - in the last page that we mapped in
- - from the file. However, we can't
- - assume to have actually obtained
- - full pages from the kernel, since
- - we didn't ask for them, and uClibc
- - may not give us full pages for
- - small allocations. So only zero
- - out up to memsz or the end of the
- - page, whichever comes first. */
- -
- - /* CPNT is the beginning of the memsz
- - portion not backed by filesz. */
- - cpnt = (char *) (status + size);
- -
- - /* MAP_SIZE is the address of the
- - beginning of the next page. */
- - map_size = (ppnt->p_vaddr + ppnt->p_filesz
- - + ADDR_ALIGN) & PAGE_ALIGN;
- -
- -#ifndef MIN
- -# define MIN(a,b) ((a) < (b) ? (a) : (b))
- -#endif
- - _dl_memset (cpnt, 0,
- - MIN (map_size
- - - (ppnt->p_vaddr
- - + ppnt->p_filesz),
- - ppnt->p_memsz
- - - ppnt->p_filesz));
- -
- - if (map_size < ppnt->p_vaddr + ppnt->p_memsz
- - && !piclib2map) {
- - tryaddr = map_size + (char*)(piclib ? libaddr : 0);
- - status = (char *) _dl_mmap(tryaddr,
- - ppnt->p_vaddr + ppnt->p_memsz - map_size,
- - LXFLAGS(ppnt->p_flags), flags | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
- - if (_dl_mmap_check_error(status)
- - || tryaddr != status)
- - goto cant_map;
- - }
- + status = map_writeable (infile, ppnt, piclib, flags, libaddr);
- + if (status == NULL)
- + goto cant_map1;
- } else {
- tryaddr = (piclib == 2 ? 0
- : (char *) (ppnt->p_vaddr & PAGE_ALIGN)
- @@ -664,11 +651,11 @@
- infile, ppnt->p_offset & OFFS_ALIGN);
- if (_dl_mmap_check_error(status)
- || (tryaddr && tryaddr != status))
- - goto cant_map;
- - DL_INIT_LOADADDR_HDR
- - (lib_loadaddr, status
- - + (ppnt->p_vaddr & ADDR_ALIGN), ppnt);
- + goto cant_map1;
- }
- + DL_INIT_LOADADDR_HDR(lib_loadaddr,
- + status + (ppnt->p_vaddr & ADDR_ALIGN),
- + ppnt);
-
- /* if (libaddr == 0 && piclib) {
- libaddr = (unsigned long) status;
- @@ -677,7 +664,6 @@
- }
- ppnt++;
- }
- - _dl_close(infile);
-
- /* For a non-PIC library, the addresses are all absolute */
- if (piclib) {
- @@ -696,6 +682,7 @@
- _dl_dprintf(2, "%s: '%s' is missing a dynamic section\n",
- _dl_progname, libname);
- _dl_munmap(header, _dl_pagesize);
- + _dl_close(infile);
- return NULL;
- }
-
- @@ -711,10 +698,23 @@
- ppnt = (ElfW(Phdr) *)(intptr_t) & header[epnt->e_phoff];
- for (i = 0; i < epnt->e_phnum; i++, ppnt++) {
- if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W)) {
- +#ifdef __ARCH_USE_MMU__
- _dl_mprotect((void *) ((piclib ? libaddr : 0) +
- (ppnt->p_vaddr & PAGE_ALIGN)),
- (ppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) ppnt->p_filesz,
- PROT_READ | PROT_WRITE | PROT_EXEC);
- +#else
- + void *new_addr;
- + new_addr = map_writeable (infile, ppnt, piclib, flags, libaddr);
- + if (!new_addr) {
- + _dl_dprintf(_dl_debug_file, "Can't modify %s's text section.",
- + libname);
- + _dl_exit(1);
- + }
- + DL_UPDATE_LOADADDR_HDR(lib_loadaddr,
- + new_addr + (ppnt->p_vaddr & ADDR_ALIGN),
- + ppnt);
- +#endif
- }
- }
- #else
- @@ -725,6 +725,8 @@
- #endif
- }
-
- + _dl_close(infile);
- +
- tpnt = _dl_add_elf_hash_table(libname, lib_loadaddr, dynamic_info,
- dynamic_addr, 0);
- tpnt->relro_addr = relro_addr;
- @@ -809,20 +811,44 @@
- #ifdef __DSBT__
- /* Handle DSBT initialization */
- {
- - struct elf_resolve *t, *ref = NULL;
- + struct elf_resolve *t, *ref;
- int idx = tpnt->loadaddr.map->dsbt_index;
- unsigned *dsbt = tpnt->loadaddr.map->dsbt_table;
-
- if (idx == 0) {
- - /* This DSO has not been assigned an index */
- - _dl_dprintf(2, "%s: '%s' is missing a dsbt index assignment!\n",
- - _dl_progname, libname);
- - _dl_exit(1);
- + if (!dynamic_info[DT_TEXTREL]) {
- + /* This DSO has not been assigned an index. */
- + _dl_dprintf(2, "%s: '%s' is missing a dsbt index assignment!\n",
- + _dl_progname, libname);
- + _dl_exit(1);
- + }
- + /* Find a dsbt table from another module. */
- + ref = NULL;
- + for (t = _dl_loaded_modules; t; t = t->next) {
- + if (ref == NULL && t != tpnt) {
- + ref = t;
- + break;
- + }
- + }
- + idx = tpnt->loadaddr.map->dsbt_size;
- + while (idx-- > 0)
- + if (!ref || ref->loadaddr.map->dsbt_table[idx] == NULL)
- + break;
- + if (idx <= 0) {
- + _dl_dprintf(2, "%s: '%s' caused DSBT table overflow!\n",
- + _dl_progname, libname);
- + _dl_exit(1);
- + }
- + _dl_if_debug_dprint("\n\tfile='%s'; assigned index %d\n",
- + libname, idx);
- + tpnt->loadaddr.map->dsbt_index = idx;
- +
- }
-
- /*
- * Setup dsbt slot for this module in dsbt of all modules.
- */
- + ref = NULL;
- for (t = _dl_loaded_modules; t; t = t->next) {
- /* find a dsbt table from another module */
- if (ref == NULL && t != tpnt) {
- diff -Nur uClibc-0.9.32-rc3/ldso/ldso/dl-startup.c uClibc/ldso/ldso/dl-startup.c
- --- uClibc-0.9.32-rc3/ldso/ldso/dl-startup.c 2011-03-16 20:11:13.000000000 +0100
- +++ uClibc/ldso/ldso/dl-startup.c 2011-04-26 16:18:21.747664948 +0200
- @@ -32,8 +32,8 @@
-
- /*
- * The main trick with this program is that initially, we ourselves are not
- - * dynamicly linked. This means that we cannot access any global variables or
- - * call any functions. No globals initially, since the Global Offset Table
- + * dynamically linked. This means that we cannot access any global variables
- + * or call any functions. No globals initially, since the Global Offset Table
- * (GOT) is initialized by the linker assuming a virtual address of 0, and no
- * function calls initially since the Procedure Linkage Table (PLT) is not yet
- * initialized.
- @@ -55,12 +55,12 @@
- *
- * Fortunately, the linker itself leaves a few clues lying around, and when the
- * kernel starts the image, there are a few further clues. First of all, there
- - * is Auxiliary Vector Table information sitting on which is provided to us by
- - * the kernel, and which includes information about the load address that the
- - * program interpreter was loaded at, the number of sections, the address the
- - * application was loaded at and so forth. Here this information is stored in
- - * the array auxvt. For details see linux/fs/binfmt_elf.c where it calls
- - * NEW_AUX_ENT() a bunch of time....
- + * is Auxiliary Vector Table information sitting on the stack which is provided
- + * to us by the kernel, and which includes information about the address
- + * that the program interpreter was loaded at, the number of sections, the
- + * address the application was loaded at, and so forth. Here this information
- + * is stored in the array auxvt. For details see linux/fs/binfmt_elf.c where
- + * it calls NEW_AUX_ENT() a bunch of times....
- *
- * Next, we need to find the GOT. On most arches there is a register pointing
- * to the GOT, but just in case (and for new ports) I've added some (slow) C
- diff -Nur uClibc-0.9.32-rc3/ldso/ldso/frv/dl-inlines.h uClibc/ldso/ldso/frv/dl-inlines.h
- --- uClibc-0.9.32-rc3/ldso/ldso/frv/dl-inlines.h 2011-03-16 20:11:13.000000000 +0100
- +++ uClibc/ldso/ldso/frv/dl-inlines.h 2011-04-26 16:18:21.757661905 +0200
- @@ -72,14 +72,39 @@
- segdata->p_memsz = phdr->p_memsz;
-
- #if defined (__SUPPORT_LD_DEBUG__)
- - {
- - extern char *_dl_debug;
- - extern int _dl_debug_file;
- - if (_dl_debug)
- - _dl_dprintf(_dl_debug_file, "%i: mapped %x at %x, size %x\n",
- - loadaddr.map->nsegs-1,
- - segdata->p_vaddr, segdata->addr, segdata->p_memsz);
- - }
- + if (_dl_debug)
- + _dl_dprintf(_dl_debug_file, "%i: mapped %x at %x, size %x\n",
- + loadaddr.map->nsegs-1,
- + segdata->p_vaddr, segdata->addr, segdata->p_memsz);
- +#endif
- +}
- +
- +/* Replace an existing entry in the load map. */
- +static __always_inline void
- +__dl_update_loadaddr_hdr (struct elf32_fdpic_loadaddr loadaddr, void *addr,
- + Elf32_Phdr *phdr)
- +{
- + struct elf32_fdpic_loadseg *segdata;
- + void *oldaddr;
- + int i;
- +
- + for (i = 0; i < loadaddr.map->nsegs; i++)
- + if (loadaddr.map->segs[i].p_vaddr == phdr->p_vaddr
- + && loadaddr.map->segs[i].p_memsz == phdr->p_memsz)
- + break;
- + if (i == loadaddr.map->nsegs)
- + _dl_exit (-1);
- +
- + segdata = loadaddr.map->segs + i;
- + oldaddr = (void *)segdata->addr;
- + _dl_munmap (oldaddr, segdata->p_memsz);
- + segdata->addr = (Elf32_Addr) addr;
- +
- +#if defined (__SUPPORT_LD_DEBUG__)
- + if (_dl_debug)
- + _dl_dprintf(_dl_debug_file, "%i: changed mapping %x at %x (old %x), size %x\n",
- + loadaddr.map->nsegs-1,
- + segdata->p_vaddr, segdata->addr, oldaddr, segdata->p_memsz);
- #endif
- }
-
- diff -Nur uClibc-0.9.32-rc3/ldso/ldso/frv/dl-sysdep.h uClibc/ldso/ldso/frv/dl-sysdep.h
- --- uClibc-0.9.32-rc3/ldso/ldso/frv/dl-sysdep.h 2011-03-16 20:11:13.000000000 +0100
- +++ uClibc/ldso/ldso/frv/dl-sysdep.h 2011-04-26 16:18:21.757661905 +0200
- @@ -95,6 +95,8 @@
- #define DL_INIT_LOADADDR_HDR(LOADADDR, ADDR, PHDR) \
- (__dl_init_loadaddr_hdr ((LOADADDR), (ADDR), (PHDR), \
- dl_init_loadaddr_load_count))
- +#define DL_UPDATE_LOADADDR_HDR(LOADADDR, ADDR, PHDR) \
- + (__dl_update_loadaddr_hdr ((LOADADDR), (ADDR), (PHDR)))
- #define DL_LOADADDR_UNMAP(LOADADDR, LEN) \
- (__dl_loadaddr_unmap ((LOADADDR), (NULL)))
- #define DL_LIB_UNMAP(LIB, LEN) \
- diff -Nur uClibc-0.9.32-rc3/ldso/ldso/mips/elfinterp.c uClibc/ldso/ldso/mips/elfinterp.c
- --- uClibc-0.9.32-rc3/ldso/ldso/mips/elfinterp.c 2011-03-16 20:11:13.000000000 +0100
- +++ uClibc/ldso/ldso/mips/elfinterp.c 2011-04-26 16:18:21.757661905 +0200
- @@ -378,8 +378,11 @@
- *got_entry += (unsigned long) tpnt->loadaddr;
- }
- else {
- + struct symbol_ref sym_ref;
- + sym_ref.sym = sym;
- + sym_ref.tpnt = NULL;
- *got_entry = (unsigned long) _dl_find_hash(strtab +
- - sym->st_name, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT, NULL);
- + sym->st_name, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT, &sym_ref);
- }
-
- got_entry++;
- diff -Nur uClibc-0.9.32-rc3/libc/inet/resolv.c uClibc/libc/inet/resolv.c
- --- uClibc-0.9.32-rc3/libc/inet/resolv.c 2011-03-16 20:11:13.000000000 +0100
- +++ uClibc/libc/inet/resolv.c 2011-04-26 16:18:21.767661585 +0200
- @@ -3009,7 +3009,7 @@
- int m = 0;
- /* free nsaddrs[m] if they do not point to nsaddr_list[x] */
- while (m < ARRAY_SIZE(_res._u._ext.nsaddrs)) {
- - char *p2 = (char*)(_res._u._ext.nsaddrs[m]);
- + char *p2 = (char*)(_res._u._ext.nsaddrs[m++]);
- if (p2 < p1 || (p2 - p1) > sizeof(_res.nsaddr_list))
- free(p2);
- }
- diff -Nur uClibc-0.9.32-rc3/libc/misc/fts/fts.c uClibc/libc/misc/fts/fts.c
- --- uClibc-0.9.32-rc3/libc/misc/fts/fts.c 1970-01-01 01:00:00.000000000 +0100
- +++ uClibc/libc/misc/fts/fts.c 2011-04-26 16:18:21.777663244 +0200
- @@ -0,0 +1,1145 @@
- +/*-
- + * Copyright (c) 1990, 1993, 1994
- + * The Regents of the University of California. All rights reserved.
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions
- + * are met:
- + * 1. Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + * 2. Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + * 4. Neither the name of the University nor the names of its contributors
- + * may be used to endorse or promote products derived from this software
- + * without specific prior written permission.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- + * SUCH DAMAGE.
- + */
- +
- +#include <sys/param.h>
- +#include <sys/stat.h>
- +#include <fcntl.h>
- +#include <dirent.h>
- +#include <errno.h>
- +#include <fts.h>
- +#include <stdlib.h>
- +#include <string.h>
- +#include <unistd.h>
- +
- +#ifdef __UCLIBC_HAS_LFS__
- +# include <_lfs_64.h>
- +#else
- +# define stat64 stat
- +# define fstat64 fstat
- +#endif
- +
- +/* Largest alignment size needed, minus one.
- + Usually long double is the worst case. */
- +#ifndef ALIGNBYTES
- +#define ALIGNBYTES (__alignof__ (long double) - 1)
- +#endif
- +/* Align P to that size. */
- +#ifndef ALIGN
- +#define ALIGN(p) (((unsigned long int) (p) + ALIGNBYTES) & ~ALIGNBYTES)
- +#endif
- +
- +
- +static FTSENT *fts_alloc (FTS *, const char *, size_t) internal_function;
- +static FTSENT *fts_build (FTS *, int) internal_function;
- +static void fts_lfree (FTSENT *) internal_function;
- +static void fts_load (FTS *, FTSENT *) internal_function;
- +static size_t fts_maxarglen (char * const *) internal_function;
- +static void fts_padjust (FTS *, FTSENT *) internal_function;
- +static int fts_palloc (FTS *, size_t) internal_function;
- +static FTSENT *fts_sort (FTS *, FTSENT *, int) internal_function;
- +static u_short fts_stat (FTS *, FTSENT *, int) internal_function;
- +static int fts_safe_changedir (FTS *, FTSENT *, int, const char *)
- + internal_function;
- +
- +#ifndef MAX
- +#define MAX(a, b) ({ __typeof__ (a) _a = (a); \
- + __typeof__ (b) _b = (b); \
- + _a > _b ? _a : _b; })
- +#endif
- +
- +#define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
- +
- +#define CLR(opt) (sp->fts_options &= ~(opt))
- +#define ISSET(opt) (sp->fts_options & (opt))
- +#define SET(opt) (sp->fts_options |= (opt))
- +
- +#define FCHDIR(sp, fd) (!ISSET(FTS_NOCHDIR) && fchdir(fd))
- +
- +/* fts_build flags */
- +#define BCHILD 1 /* fts_children */
- +#define BNAMES 2 /* fts_children, names only */
- +#define BREAD 3 /* fts_read */
- +
- +FTS *
- +fts_open(argv, options, compar)
- + char * const *argv;
- + register int options;
- + int (*compar) (const FTSENT **, const FTSENT **);
- +{
- + register FTS *sp;
- + register FTSENT *p, *root;
- + register int nitems;
- + FTSENT *parent = NULL;
- + FTSENT *tmp = NULL;
- +
- + /* Options check. */
- + if (options & ~FTS_OPTIONMASK) {
- + __set_errno (EINVAL);
- + return (NULL);
- + }
- +
- + /* Allocate/initialize the stream */
- + if ((sp = malloc((u_int)sizeof(FTS))) == NULL)
- + return (NULL);
- + memset(sp, 0, sizeof(FTS));
- + sp->fts_compar = (int (*) (const void *, const void *)) compar;
- + sp->fts_options = options;
- +
- + /* Logical walks turn on NOCHDIR; symbolic links are too hard. */
- + if (ISSET(FTS_LOGICAL))
- + SET(FTS_NOCHDIR);
- +
- + /*
- + * Start out with 1K of path space, and enough, in any case,
- + * to hold the user's paths.
- + */
- +#ifndef MAXPATHLEN
- +#define MAXPATHLEN 1024
- +#endif
- + size_t maxarglen = fts_maxarglen(argv);
- + if (fts_palloc(sp, MAX(maxarglen, MAXPATHLEN)))
- + goto mem1;
- +
- + /* Allocate/initialize root's parent. */
- + if (*argv != NULL) {
- + if ((parent = fts_alloc(sp, "", 0)) == NULL)
- + goto mem2;
- + parent->fts_level = FTS_ROOTPARENTLEVEL;
- + }
- +
- + /* Allocate/initialize root(s). */
- + for (root = NULL, nitems = 0; *argv != NULL; ++argv, ++nitems) {
- + /* Don't allow zero-length paths. */
- + size_t len = strlen(*argv);
- + if (len == 0) {
- + __set_errno (ENOENT);
- + goto mem3;
- + }
- +
- + p = fts_alloc(sp, *argv, len);
- + p->fts_level = FTS_ROOTLEVEL;
- + p->fts_parent = parent;
- + p->fts_accpath = p->fts_name;
- + p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW));
- +
- + /* Command-line "." and ".." are real directories. */
- + if (p->fts_info == FTS_DOT)
- + p->fts_info = FTS_D;
- +
- + /*
- + * If comparison routine supplied, traverse in sorted
- + * order; otherwise traverse in the order specified.
- + */
- + if (compar) {
- + p->fts_link = root;
- + root = p;
- + } else {
- + p->fts_link = NULL;
- + if (root == NULL)
- + tmp = root = p;
- + else {
- + tmp->fts_link = p;
- + tmp = p;
- + }
- + }
- + }
- + if (compar && nitems > 1)
- + root = fts_sort(sp, root, nitems);
- +
- + /*
- + * Allocate a dummy pointer and make fts_read think that we've just
- + * finished the node before the root(s); set p->fts_info to FTS_INIT
- + * so that everything about the "current" node is ignored.
- + */
- + if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL)
- + goto mem3;
- + sp->fts_cur->fts_link = root;
- + sp->fts_cur->fts_info = FTS_INIT;
- +
- + /*
- + * If using chdir(2), grab a file descriptor pointing to dot to ensure
- + * that we can get back here; this could be avoided for some paths,
- + * but almost certainly not worth the effort. Slashes, symbolic links,
- + * and ".." are all fairly nasty problems. Note, if we can't get the
- + * descriptor we run anyway, just more slowly.
- + */
- + if (!ISSET(FTS_NOCHDIR)
- + && (sp->fts_rfd = open(".", O_RDONLY, 0)) < 0)
- + SET(FTS_NOCHDIR);
- +
- + return (sp);
- +
- +mem3: fts_lfree(root);
- + free(parent);
- +mem2: free(sp->fts_path);
- +mem1: free(sp);
- + return (NULL);
- +}
- +
- +static void
- +internal_function
- +fts_load(sp, p)
- + FTS *sp;
- + register FTSENT *p;
- +{
- + register int len;
- + register char *cp;
- +
- + /*
- + * Load the stream structure for the next traversal. Since we don't
- + * actually enter the directory until after the preorder visit, set
- + * the fts_accpath field specially so the chdir gets done to the right
- + * place and the user can access the first node. From fts_open it's
- + * known that the path will fit.
- + */
- + len = p->fts_pathlen = p->fts_namelen;
- + memmove(sp->fts_path, p->fts_name, len + 1);
- + if ((cp = strrchr(p->fts_name, '/')) && (cp != p->fts_name || cp[1])) {
- + len = strlen(++cp);
- + memmove(p->fts_name, cp, len + 1);
- + p->fts_namelen = len;
- + }
- + p->fts_accpath = p->fts_path = sp->fts_path;
- + sp->fts_dev = p->fts_dev;
- +}
- +
- +int
- +fts_close(sp)
- + FTS *sp;
- +{
- + register FTSENT *freep, *p;
- + int saved_errno;
- +
- + /*
- + * This still works if we haven't read anything -- the dummy structure
- + * points to the root list, so we step through to the end of the root
- + * list which has a valid parent pointer.
- + */
- + if (sp->fts_cur) {
- + for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) {
- + freep = p;
- + p = p->fts_link != NULL ? p->fts_link : p->fts_parent;
- + free(freep);
- + }
- + free(p);
- + }
- +
- + /* Free up child linked list, sort array, path buffer. */
- + if (sp->fts_child)
- + fts_lfree(sp->fts_child);
- + free(sp->fts_array);
- + free(sp->fts_path);
- +
- + /* Return to original directory, save errno if necessary. */
- + if (!ISSET(FTS_NOCHDIR)) {
- + saved_errno = fchdir(sp->fts_rfd) ? errno : 0;
- + (void)close(sp->fts_rfd);
- +
- + /* Set errno and return. */
- + if (saved_errno != 0) {
- + /* Free up the stream pointer. */
- + free(sp);
- + __set_errno (saved_errno);
- + return (-1);
- + }
- + }
- +
- + /* Free up the stream pointer. */
- + free(sp);
- + return (0);
- +}
- +
- +/*
- + * Special case of "/" at the end of the path so that slashes aren't
- + * appended which would cause paths to be written as "....//foo".
- + */
- +#define NAPPEND(p) \
- + (p->fts_path[p->fts_pathlen - 1] == '/' \
- + ? p->fts_pathlen - 1 : p->fts_pathlen)
- +
- +FTSENT *
- +fts_read(sp)
- + register FTS *sp;
- +{
- + register FTSENT *p, *tmp;
- + register int instr;
- + register char *t;
- + int saved_errno;
- +
- + /* If finished or unrecoverable error, return NULL. */
- + if (sp->fts_cur == NULL || ISSET(FTS_STOP))
- + return (NULL);
- +
- + /* Set current node pointer. */
- + p = sp->fts_cur;
- +
- + /* Save and zero out user instructions. */
- + instr = p->fts_instr;
- + p->fts_instr = FTS_NOINSTR;
- +
- + /* Any type of file may be re-visited; re-stat and re-turn. */
- + if (instr == FTS_AGAIN) {
- + p->fts_info = fts_stat(sp, p, 0);
- + return (p);
- + }
- +
- + /*
- + * Following a symlink -- SLNONE test allows application to see
- + * SLNONE and recover. If indirecting through a symlink, have
- + * keep a pointer to current location. If unable to get that
- + * pointer, follow fails.
- + */
- + if (instr == FTS_FOLLOW &&
- + (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) {
- + p->fts_info = fts_stat(sp, p, 1);
- + if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
- + if ((p->fts_symfd = open(".", O_RDONLY, 0)) < 0) {
- + p->fts_errno = errno;
- + p->fts_info = FTS_ERR;
- + } else
- + p->fts_flags |= FTS_SYMFOLLOW;
- + }
- + return (p);
- + }
- +
- + /* Directory in pre-order. */
- + if (p->fts_info == FTS_D) {
- + /* If skipped or crossed mount point, do post-order visit. */
- + if (instr == FTS_SKIP ||
- + (ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev)) {
- + if (p->fts_flags & FTS_SYMFOLLOW)
- + (void)close(p->fts_symfd);
- + if (sp->fts_child) {
- + fts_lfree(sp->fts_child);
- + sp->fts_child = NULL;
- + }
- + p->fts_info = FTS_DP;
- + return (p);
- + }
- +
- + /* Rebuild if only read the names and now traversing. */
- + if (sp->fts_child != NULL && ISSET(FTS_NAMEONLY)) {
- + CLR(FTS_NAMEONLY);
- + fts_lfree(sp->fts_child);
- + sp->fts_child = NULL;
- + }
- +
- + /*
- + * Cd to the subdirectory.
- + *
- + * If have already read and now fail to chdir, whack the list
- + * to make the names come out right, and set the parent errno
- + * so the application will eventually get an error condition.
- + * Set the FTS_DONTCHDIR flag so that when we logically change
- + * directories back to the parent we don't do a chdir.
- + *
- + * If haven't read do so. If the read fails, fts_build sets
- + * FTS_STOP or the fts_info field of the node.
- + */
- + if (sp->fts_child != NULL) {
- + if (fts_safe_changedir(sp, p, -1, p->fts_accpath)) {
- + p->fts_errno = errno;
- + p->fts_flags |= FTS_DONTCHDIR;
- + for (p = sp->fts_child; p != NULL;
- + p = p->fts_link)
- + p->fts_accpath =
- + p->fts_parent->fts_accpath;
- + }
- + } else if ((sp->fts_child = fts_build(sp, BREAD)) == NULL) {
- + if (ISSET(FTS_STOP))
- + return (NULL);
- + return (p);
- + }
- + p = sp->fts_child;
- + sp->fts_child = NULL;
- + sp->fts_cur = p;
- + goto name;
- + }
- +
- + /* Move to the next node on this level. */
- +next: tmp = p;
- + if ((p = p->fts_link) != NULL) {
- + sp->fts_cur = p;
- + free(tmp);
- +
- + /*
- + * If reached the top, return to the original directory (or
- + * the root of the tree), and load the paths for the next root.
- + */
- + if (p->fts_level == FTS_ROOTLEVEL) {
- + if (FCHDIR(sp, sp->fts_rfd)) {
- + SET(FTS_STOP);
- + return (NULL);
- + }
- + fts_load(sp, p);
- + return p;
- + }
- +
- + /*
- + * User may have called fts_set on the node. If skipped,
- + * ignore. If followed, get a file descriptor so we can
- + * get back if necessary.
- + */
- + if (p->fts_instr == FTS_SKIP)
- + goto next;
- + if (p->fts_instr == FTS_FOLLOW) {
- + p->fts_info = fts_stat(sp, p, 1);
- + if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
- + if ((p->fts_symfd =
- + open(".", O_RDONLY, 0)) < 0) {
- + p->fts_errno = errno;
- + p->fts_info = FTS_ERR;
- + } else
- + p->fts_flags |= FTS_SYMFOLLOW;
- + }
- + p->fts_instr = FTS_NOINSTR;
- + }
- +
- +name: t = sp->fts_path + NAPPEND(p->fts_parent);
- + *t++ = '/';
- + memmove(t, p->fts_name, p->fts_namelen + 1);
- + return p;
- + }
- +
- + /* Move up to the parent node. */
- + p = tmp->fts_parent;
- + sp->fts_cur = p;
- + free(tmp);
- +
- + if (p->fts_level == FTS_ROOTPARENTLEVEL) {
- + /*
- + * Done; free everything up and set errno to 0 so the user
- + * can distinguish between error and EOF.
- + */
- + free(p);
- + __set_errno (0);
- + return (sp->fts_cur = NULL);
- + }
- +
- + /* NUL terminate the pathname. */
- + sp->fts_path[p->fts_pathlen] = '\0';
- +
- + /*
- + * Return to the parent directory. If at a root node or came through
- + * a symlink, go back through the file descriptor. Otherwise, cd up
- + * one directory.
- + */
- + if (p->fts_level == FTS_ROOTLEVEL) {
- + if (FCHDIR(sp, sp->fts_rfd)) {
- + SET(FTS_STOP);
- + return (NULL);
- + }
- + } else if (p->fts_flags & FTS_SYMFOLLOW) {
- + if (FCHDIR(sp, p->fts_symfd)) {
- + saved_errno = errno;
- + (void)close(p->fts_symfd);
- + __set_errno (saved_errno);
- + SET(FTS_STOP);
- + return (NULL);
- + }
- + (void)close(p->fts_symfd);
- + } else if (!(p->fts_flags & FTS_DONTCHDIR) &&
- + fts_safe_changedir(sp, p->fts_parent, -1, "..")) {
- + SET(FTS_STOP);
- + return (NULL);
- + }
- + p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP;
- + return p;
- +}
- +
- +/*
- + * Fts_set takes the stream as an argument although it's not used in this
- + * implementation; it would be necessary if anyone wanted to add global
- + * semantics to fts using fts_set. An error return is allowed for similar
- + * reasons.
- + */
- +/* ARGSUSED */
- +int
- +fts_set(sp, p, instr)
- + FTS *sp;
- + FTSENT *p;
- + int instr;
- +{
- + if (instr != 0 && instr != FTS_AGAIN && instr != FTS_FOLLOW &&
- + instr != FTS_NOINSTR && instr != FTS_SKIP) {
- + __set_errno (EINVAL);
- + return (1);
- + }
- + p->fts_instr = instr;
- + return (0);
- +}
- +
- +FTSENT *
- +fts_children(sp, instr)
- + register FTS *sp;
- + int instr;
- +{
- + register FTSENT *p;
- + int fd;
- +
- + if (instr != 0 && instr != FTS_NAMEONLY) {
- + __set_errno (EINVAL);
- + return (NULL);
- + }
- +
- + /* Set current node pointer. */
- + p = sp->fts_cur;
- +
- + /*
- + * Errno set to 0 so user can distinguish empty directory from
- + * an error.
- + */
- + __set_errno (0);
- +
- + /* Fatal errors stop here. */
- + if (ISSET(FTS_STOP))
- + return (NULL);
- +
- + /* Return logical hierarchy of user's arguments. */
- + if (p->fts_info == FTS_INIT)
- + return (p->fts_link);
- +
- + /*
- + * If not a directory being visited in pre-order, stop here. Could
- + * allow FTS_DNR, assuming the user has fixed the problem, but the
- + * same effect is available with FTS_AGAIN.
- + */
- + if (p->fts_info != FTS_D /* && p->fts_info != FTS_DNR */)
- + return (NULL);
- +
- + /* Free up any previous child list. */
- + if (sp->fts_child != NULL)
- + fts_lfree(sp->fts_child);
- +
- + if (instr == FTS_NAMEONLY) {
- + SET(FTS_NAMEONLY);
- + instr = BNAMES;
- + } else
- + instr = BCHILD;
- +
- + /*
- + * If using chdir on a relative path and called BEFORE fts_read does
- + * its chdir to the root of a traversal, we can lose -- we need to
- + * chdir into the subdirectory, and we don't know where the current
- + * directory is, so we can't get back so that the upcoming chdir by
- + * fts_read will work.
- + */
- + if (p->fts_level != FTS_ROOTLEVEL || p->fts_accpath[0] == '/' ||
- + ISSET(FTS_NOCHDIR))
- + return (sp->fts_child = fts_build(sp, instr));
- +
- + if ((fd = open(".", O_RDONLY, 0)) < 0)
- + return (NULL);
- + sp->fts_child = fts_build(sp, instr);
- + if (fchdir(fd))
- + return (NULL);
- + (void)close(fd);
- + return (sp->fts_child);
- +}
- +
- +/*
- + * This is the tricky part -- do not casually change *anything* in here. The
- + * idea is to build the linked list of entries that are used by fts_children
- + * and fts_read. There are lots of special cases.
- + *
- + * The real slowdown in walking the tree is the stat calls. If FTS_NOSTAT is
- + * set and it's a physical walk (so that symbolic links can't be directories),
- + * we can do things quickly. First, if it's a 4.4BSD file system, the type
- + * of the file is in the directory entry. Otherwise, we assume that the number
- + * of subdirectories in a node is equal to the number of links to the parent.
- + * The former skips all stat calls. The latter skips stat calls in any leaf
- + * directories and for any files after the subdirectories in the directory have
- + * been found, cutting the stat calls by about 2/3.
- + */
- +static FTSENT *
- +internal_function
- +fts_build(sp, type)
- + register FTS *sp;
- + int type;
- +{
- + register struct dirent *dp;
- + register FTSENT *p, *head;
- + register int nitems;
- + FTSENT *cur, *tail;
- + DIR *dirp;
- + void *oldaddr;
- + int cderrno, descend, len, level, nlinks, saved_errno,
- + nostat, doadjust;
- + size_t maxlen;
- + char *cp;
- +
- + /* Set current node pointer. */
- + cur = sp->fts_cur;
- +
- + /*
- + * Open the directory for reading. If this fails, we're done.
- + * If being called from fts_read, set the fts_info field.
- + */
- +#if defined FTS_WHITEOUT && 0
- + if (ISSET(FTS_WHITEOUT))
- + oflag = DTF_NODUP|DTF_REWIND;
- + else
- + oflag = DTF_HIDEW|DTF_NODUP|DTF_REWIND;
- +#else
- +# define opendir2(path, flag) opendir(path)
- +#endif
- + if ((dirp = opendir2(cur->fts_accpath, oflag)) == NULL) {
- + if (type == BREAD) {
- + cur->fts_info = FTS_DNR;
- + cur->fts_errno = errno;
- + }
- + return (NULL);
- + }
- +
- + /*
- + * Nlinks is the number of possible entries of type directory in the
- + * directory if we're cheating on stat calls, 0 if we're not doing
- + * any stat calls at all, -1 if we're doing stats on everything.
- + */
- + if (type == BNAMES) {
- + nlinks = 0;
- + /* Be quiet about nostat, GCC. */
- + nostat = 0;
- + } else if (ISSET(FTS_NOSTAT) && ISSET(FTS_PHYSICAL)) {
- + nlinks = cur->fts_nlink - (ISSET(FTS_SEEDOT) ? 0 : 2);
- + nostat = 1;
- + } else {
- + nlinks = -1;
- + nostat = 0;
- + }
- +
- +#ifdef notdef
- + (void)printf("nlinks == %d (cur: %d)\n", nlinks, cur->fts_nlink);
- + (void)printf("NOSTAT %d PHYSICAL %d SEEDOT %d\n",
- + ISSET(FTS_NOSTAT), ISSET(FTS_PHYSICAL), ISSET(FTS_SEEDOT));
- +#endif
- + /*
- + * If we're going to need to stat anything or we want to descend
- + * and stay in the directory, chdir. If this fails we keep going,
- + * but set a flag so we don't chdir after the post-order visit.
- + * We won't be able to stat anything, but we can still return the
- + * names themselves. Note, that since fts_read won't be able to
- + * chdir into the directory, it will have to return different path
- + * names than before, i.e. "a/b" instead of "b". Since the node
- + * has already been visited in pre-order, have to wait until the
- + * post-order visit to return the error. There is a special case
- + * here, if there was nothing to stat then it's not an error to
- + * not be able to stat. This is all fairly nasty. If a program
- + * needed sorted entries or stat information, they had better be
- + * checking FTS_NS on the returned nodes.
- + */
- + cderrno = 0;
- + if (nlinks || type == BREAD) {
- + if (fts_safe_changedir(sp, cur, dirfd(dirp), NULL)) {
- + if (nlinks && type == BREAD)
- + cur->fts_errno = errno;
- + cur->fts_flags |= FTS_DONTCHDIR;
- + descend = 0;
- + cderrno = errno;
- + (void)closedir(dirp);
- + dirp = NULL;
- + } else
- + descend = 1;
- + } else
- + descend = 0;
- +
- + /*
- + * Figure out the max file name length that can be stored in the
- + * current path -- the inner loop allocates more path as necessary.
- + * We really wouldn't have to do the maxlen calculations here, we
- + * could do them in fts_read before returning the path, but it's a
- + * lot easier here since the length is part of the dirent structure.
- + *
- + * If not changing directories set a pointer so that can just append
- + * each new name into the path.
- + */
- + len = NAPPEND(cur);
- + if (ISSET(FTS_NOCHDIR)) {
- + cp = sp->fts_path + len;
- + *cp++ = '/';
- + } else {
- + /* GCC, you're too verbose. */
- + cp = NULL;
- + }
- + len++;
- + maxlen = sp->fts_pathlen - len;
- +
- + level = cur->fts_level + 1;
- +
- + /* Read the directory, attaching each entry to the `link' pointer. */
- + doadjust = 0;
- + for (head = tail = NULL, nitems = 0; dirp && (dp = readdir(dirp));) {
- + if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name))
- + continue;
- +
- + if ((p = fts_alloc(sp, dp->d_name, _D_EXACT_NAMLEN (dp))) == NULL)
- + goto mem1;
- + if (_D_EXACT_NAMLEN (dp) >= maxlen) {/* include space for NUL */
- + oldaddr = sp->fts_path;
- + if (fts_palloc(sp, _D_EXACT_NAMLEN (dp) + len + 1)) {
- + /*
- + * No more memory for path or structures. Save
- + * errno, free up the current structure and the
- + * structures already allocated.
- + */
- +mem1: saved_errno = errno;
- + free(p);
- + fts_lfree(head);
- + (void)closedir(dirp);
- + cur->fts_info = FTS_ERR;
- + SET(FTS_STOP);
- + __set_errno (saved_errno);
- + return (NULL);
- + }
- + /* Did realloc() change the pointer? */
- + if (oldaddr != sp->fts_path) {
- + doadjust = 1;
- + if (ISSET(FTS_NOCHDIR))
- + cp = sp->fts_path + len;
- + }
- + maxlen = sp->fts_pathlen - len;
- + }
- +
- + if (len + _D_EXACT_NAMLEN (dp) >= USHRT_MAX) {
- + /*
- + * In an FTSENT, fts_pathlen is a u_short so it is
- + * possible to wraparound here. If we do, free up
- + * the current structure and the structures already
- + * allocated, then error out with ENAMETOOLONG.
- + */
- + free(p);
- + fts_lfree(head);
- + (void)closedir(dirp);
- + cur->fts_info = FTS_ERR;
- + SET(FTS_STOP);
- + __set_errno (ENAMETOOLONG);
- + return (NULL);
- + }
- + p->fts_level = level;
- + p->fts_parent = sp->fts_cur;
- + p->fts_pathlen = len + _D_EXACT_NAMLEN (dp);
- +
- +#if defined FTS_WHITEOUT && 0
- + if (dp->d_type == DT_WHT)
- + p->fts_flags |= FTS_ISW;
- +#endif
- +
- +#if 0
- + /* Unreachable code. cderrno is only ever set to a nonnull
- + value if dirp is closed at the same time. But then we
- + cannot enter this loop. */
- + if (cderrno) {
- + if (nlinks) {
- + p->fts_info = FTS_NS;
- + p->fts_errno = cderrno;
- + } else
- + p->fts_info = FTS_NSOK;
- + p->fts_accpath = cur->fts_accpath;
- + } else
- +#endif
- + if (nlinks == 0
- +#if defined DT_DIR && defined _DIRENT_HAVE_D_TYPE
- + || (nostat &&
- + dp->d_type != DT_DIR && dp->d_type != DT_UNKNOWN)
- +#endif
- + ) {
- + p->fts_accpath =
- + ISSET(FTS_NOCHDIR) ? p->fts_path : p->fts_name;
- + p->fts_info = FTS_NSOK;
- + } else {
- + /* Build a file name for fts_stat to stat. */
- + if (ISSET(FTS_NOCHDIR)) {
- + p->fts_accpath = p->fts_path;
- + memmove(cp, p->fts_name, p->fts_namelen + 1);
- + } else
- + p->fts_accpath = p->fts_name;
- + /* Stat it. */
- + p->fts_info = fts_stat(sp, p, 0);
- +
- + /* Decrement link count if applicable. */
- + if (nlinks > 0 && (p->fts_info == FTS_D ||
- + p->fts_info == FTS_DC || p->fts_info == FTS_DOT))
- + --nlinks;
- + }
- +
- + /* We walk in directory order so "ls -f" doesn't get upset. */
- + p->fts_link = NULL;
- + if (head == NULL)
- + head = tail = p;
- + else {
- + tail->fts_link = p;
- + tail = p;
- + }
- + ++nitems;
- + }
- + if (dirp)
- + (void)closedir(dirp);
- +
- + /*
- + * If realloc() changed the address of the path, adjust the
- + * addresses for the rest of the tree and the dir list.
- + */
- + if (doadjust)
- + fts_padjust(sp, head);
- +
- + /*
- + * If not changing directories, reset the path back to original
- + * state.
- + */
- + if (ISSET(FTS_NOCHDIR)) {
- + if (len == sp->fts_pathlen || nitems == 0)
- + --cp;
- + *cp = '\0';
- + }
- +
- + /*
- + * If descended after called from fts_children or after called from
- + * fts_read and nothing found, get back. At the root level we use
- + * the saved fd; if one of fts_open()'s arguments is a relative path
- + * to an empty directory, we wind up here with no other way back. If
- + * can't get back, we're done.
- + */
- + if (descend && (type == BCHILD || !nitems) &&
- + (cur->fts_level == FTS_ROOTLEVEL ?
- + FCHDIR(sp, sp->fts_rfd) :
- + fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) {
- + cur->fts_info = FTS_ERR;
- + SET(FTS_STOP);
- + fts_lfree(head);
- + return (NULL);
- + }
- +
- + /* If didn't find anything, return NULL. */
- + if (!nitems) {
- + if (type == BREAD)
- + cur->fts_info = FTS_DP;
- + fts_lfree(head);
- + return (NULL);
- + }
- +
- + /* Sort the entries. */
- + if (sp->fts_compar && nitems > 1)
- + head = fts_sort(sp, head, nitems);
- + return (head);
- +}
- +
- +static u_short
- +internal_function
- +fts_stat(sp, p, follow)
- + FTS *sp;
- + register FTSENT *p;
- + int follow;
- +{
- + register FTSENT *t;
- + register dev_t dev;
- + register ino_t ino;
- + struct stat *sbp, sb;
- + int saved_errno;
- +
- + /* If user needs stat info, stat buffer already allocated. */
- + sbp = ISSET(FTS_NOSTAT) ? &sb : p->fts_statp;
- +
- +#if defined FTS_WHITEOUT && 0
- + /* check for whiteout */
- + if (p->fts_flags & FTS_ISW) {
- + if (sbp != &sb) {
- + memset(sbp, '\0', sizeof (*sbp));
- + sbp->st_mode = S_IFWHT;
- + }
- + return (FTS_W);
- + }
- +#endif
- +
- + /*
- + * If doing a logical walk, or application requested FTS_FOLLOW, do
- + * a stat(2). If that fails, check for a non-existent symlink. If
- + * fail, set the errno from the stat call.
- + */
- + if (ISSET(FTS_LOGICAL) || follow) {
- + if (stat(p->fts_accpath, sbp)) {
- + saved_errno = errno;
- + if (!lstat(p->fts_accpath, sbp)) {
- + __set_errno (0);
- + return (FTS_SLNONE);
- + }
- + p->fts_errno = saved_errno;
- + goto err;
- + }
- + } else if (lstat(p->fts_accpath, sbp)) {
- + p->fts_errno = errno;
- +err: memset(sbp, 0, sizeof(struct stat));
- + return (FTS_NS);
- + }
- +
- + if (S_ISDIR(sbp->st_mode)) {
- + /*
- + * Set the device/inode. Used to find cycles and check for
- + * crossing mount points. Also remember the link count, used
- + * in fts_build to limit the number of stat calls. It is
- + * understood that these fields are only referenced if fts_info
- + * is set to FTS_D.
- + */
- + dev = p->fts_dev = sbp->st_dev;
- + ino = p->fts_ino = sbp->st_ino;
- + p->fts_nlink = sbp->st_nlink;
- +
- + if (ISDOT(p->fts_name))
- + return (FTS_DOT);
- +
- + /*
- + * Cycle detection is done by brute force when the directory
- + * is first encountered. If the tree gets deep enough or the
- + * number of symbolic links to directories is high enough,
- + * something faster might be worthwhile.
- + */
- + for (t = p->fts_parent;
- + t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent)
- + if (ino == t->fts_ino && dev == t->fts_dev) {
- + p->fts_cycle = t;
- + return (FTS_DC);
- + }
- + return (FTS_D);
- + }
- + if (S_ISLNK(sbp->st_mode))
- + return (FTS_SL);
- + if (S_ISREG(sbp->st_mode))
- + return (FTS_F);
- + return (FTS_DEFAULT);
- +}
- +
- +static FTSENT *
- +internal_function
- +fts_sort(sp, head, nitems)
- + FTS *sp;
- + FTSENT *head;
- + register int nitems;
- +{
- + register FTSENT **ap, *p;
- +
- + /*
- + * Construct an array of pointers to the structures and call qsort(3).
- + * Reassemble the array in the order returned by qsort. If unable to
- + * sort for memory reasons, return the directory entries in their
- + * current order. Allocate enough space for the current needs plus
- + * 40 so don't realloc one entry at a time.
- + */
- + if (nitems > sp->fts_nitems) {
- + struct _ftsent **a;
- +
- + sp->fts_nitems = nitems + 40;
- + if ((a = realloc(sp->fts_array,
- + (size_t)(sp->fts_nitems * sizeof(FTSENT *)))) == NULL) {
- + free(sp->fts_array);
- + sp->fts_array = NULL;
- + sp->fts_nitems = 0;
- + return (head);
- + }
- + sp->fts_array = a;
- + }
- + for (ap = sp->fts_array, p = head; p; p = p->fts_link)
- + *ap++ = p;
- + qsort((void *)sp->fts_array, nitems, sizeof(FTSENT *), sp->fts_compar);
- + for (head = *(ap = sp->fts_array); --nitems; ++ap)
- + ap[0]->fts_link = ap[1];
- + ap[0]->fts_link = NULL;
- + return (head);
- +}
- +
- +static FTSENT *
- +internal_function
- +fts_alloc(sp, name, namelen)
- + FTS *sp;
- + const char *name;
- + size_t namelen;
- +{
- + register FTSENT *p;
- + size_t len;
- +
- + /*
- + * The file name is a variable length array and no stat structure is
- + * necessary if the user has set the nostat bit. Allocate the FTSENT
- + * structure, the file name and the stat structure in one chunk, but
- + * be careful that the stat structure is reasonably aligned. Since the
- + * fts_name field is declared to be of size 1, the fts_name pointer is
- + * namelen + 2 before the first possible address of the stat structure.
- + */
- + len = sizeof(FTSENT) + namelen;
- + if (!ISSET(FTS_NOSTAT))
- + len += sizeof(struct stat) + ALIGNBYTES;
- + if ((p = malloc(len)) == NULL)
- + return (NULL);
- +
- + /* Copy the name and guarantee NUL termination. */
- + memmove(p->fts_name, name, namelen);
- + p->fts_name[namelen] = '\0';
- +
- + if (!ISSET(FTS_NOSTAT))
- + p->fts_statp = (struct stat *)ALIGN(p->fts_name + namelen + 2);
- + p->fts_namelen = namelen;
- + p->fts_path = sp->fts_path;
- + p->fts_errno = 0;
- + p->fts_flags = 0;
- + p->fts_instr = FTS_NOINSTR;
- + p->fts_number = 0;
- + p->fts_pointer = NULL;
- + return (p);
- +}
- +
- +static void
- +internal_function
- +fts_lfree(head)
- + register FTSENT *head;
- +{
- + register FTSENT *p;
- +
- + /* Free a linked list of structures. */
- + while ((p = head)) {
- + head = head->fts_link;
- + free(p);
- + }
- +}
- +
- +/*
- + * Allow essentially unlimited paths; find, rm, ls should all work on any tree.
- + * Most systems will allow creation of paths much longer than MAXPATHLEN, even
- + * though the kernel won't resolve them. Add the size (not just what's needed)
- + * plus 256 bytes so don't realloc the path 2 bytes at a time.
- + */
- +static int
- +internal_function
- +fts_palloc(sp, more)
- + FTS *sp;
- + size_t more;
- +{
- + char *p;
- +
- + sp->fts_pathlen += more + 256;
- + /*
- + * Check for possible wraparound. In an FTS, fts_pathlen is
- + * a signed int but in an FTSENT it is an unsigned short.
- + * We limit fts_pathlen to USHRT_MAX to be safe in both cases.
- + */
- + if (sp->fts_pathlen < 0 || sp->fts_pathlen >= USHRT_MAX) {
- + free(sp->fts_path);
- + sp->fts_path = NULL;
- + __set_errno (ENAMETOOLONG);
- + return (1);
- + }
- + p = realloc(sp->fts_path, sp->fts_pathlen);
- + if (p == NULL) {
- + free(sp->fts_path);
- + sp->fts_path = NULL;
- + return 1;
- + }
- + sp->fts_path = p;
- + return 0;
- +}
- +
- +/*
- + * When the path is realloc'd, have to fix all of the pointers in structures
- + * already returned.
- + */
- +static void
- +internal_function
- +fts_padjust(sp, head)
- + FTS *sp;
- + FTSENT *head;
- +{
- + FTSENT *p;
- + char *addr = sp->fts_path;
- +
- +#define ADJUST(p) do { \
- + if ((p)->fts_accpath != (p)->fts_name) { \
- + (p)->fts_accpath = \
- + (char *)addr + ((p)->fts_accpath - (p)->fts_path); \
- + } \
- + (p)->fts_path = addr; \
- +} while (0)
- + /* Adjust the current set of children. */
- + for (p = sp->fts_child; p; p = p->fts_link)
- + ADJUST(p);
- +
- + /* Adjust the rest of the tree, including the current level. */
- + for (p = head; p->fts_level >= FTS_ROOTLEVEL;) {
- + ADJUST(p);
- + p = p->fts_link ? p->fts_link : p->fts_parent;
- + }
- +}
- +
- +static size_t
- +internal_function
- +fts_maxarglen(argv)
- + char * const *argv;
- +{
- + size_t len, max;
- +
- + for (max = 0; *argv; ++argv)
- + if ((len = strlen(*argv)) > max)
- + max = len;
- + return (max + 1);
- +}
- +
- +/*
- + * Change to dir specified by fd or p->fts_accpath without getting
- + * tricked by someone changing the world out from underneath us.
- + * Assumes p->fts_dev and p->fts_ino are filled in.
- + */
- +static int
- +internal_function
- +fts_safe_changedir(sp, p, fd, path)
- + FTS *sp;
- + FTSENT *p;
- + int fd;
- + const char *path;
- +{
- + int ret, oerrno, newfd;
- + struct stat64 sb;
- +
- + newfd = fd;
- + if (ISSET(FTS_NOCHDIR))
- + return (0);
- + if (fd < 0 && (newfd = open(path, O_RDONLY, 0)) < 0)
- + return (-1);
- + if (fstat64(newfd, &sb)) {
- + ret = -1;
- + goto bail;
- + }
- + if (p->fts_dev != sb.st_dev || p->fts_ino != sb.st_ino) {
- + __set_errno (ENOENT); /* disinformation */
- + ret = -1;
- + goto bail;
- + }
- + ret = fchdir(newfd);
- +bail:
- + oerrno = errno;
- + if (fd < 0)
- + (void)close(newfd);
- + __set_errno (oerrno);
- + return (ret);
- +}
- diff -Nur uClibc-0.9.32-rc3/libc/misc/fts/Makefile uClibc/libc/misc/fts/Makefile
- --- uClibc-0.9.32-rc3/libc/misc/fts/Makefile 1970-01-01 01:00:00.000000000 +0100
- +++ uClibc/libc/misc/fts/Makefile 2011-04-26 16:18:21.777663244 +0200
- @@ -0,0 +1,14 @@
- +# Makefile for uClibc
- +#
- +# Copyright (C) 2009 STMicroelectronics Ltd.
- +# Author: Salvatore Cro <salvatore.cro at st.com>
- +#
- +# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
- +#
- +
- +top_srcdir=../../../
- +top_builddir=../../../
- +all: objs
- +include $(top_builddir)Rules.mak
- +include Makefile.in
- +include $(top_srcdir)Makerules
- diff -Nur uClibc-0.9.32-rc3/libc/misc/fts/Makefile.in uClibc/libc/misc/fts/Makefile.in
- --- uClibc-0.9.32-rc3/libc/misc/fts/Makefile.in 1970-01-01 01:00:00.000000000 +0100
- +++ uClibc/libc/misc/fts/Makefile.in 2011-04-26 16:18:21.777663244 +0200
- @@ -0,0 +1,23 @@
- +# FTS Makefile for uClibc
- +#
- +# Copyright (C) 2009 STMicroelectronics Ltd.
- +# Author: Salvatore Cro <salvatore.cro at st.com>
- +#
- +# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
- +#
- +
- +subdirs += libc/misc/fts
- +CSRC := fts.c
- +
- +MISC_FTS_DIR := $(top_srcdir)libc/misc/fts
- +MISC_FTS_OUT := $(top_builddir)libc/misc/fts
- +
- +MISC_FTS_SRC := $(patsubst %.c,$(MISC_FTS_DIR)/%.c,$(CSRC))
- +MISC_FTS_OBJ := $(patsubst %.c,$(MISC_FTS_OUT)/%.o,$(CSRC))
- +
- +libc-$(UCLIBC_HAS_FTS) += $(MISC_FTS_OBJ)
- +
- +objclean-y += CLEAN_libc/misc/fts
- +
- +CLEAN_libc/misc/fts:
- + $(do_rm) $(addprefix $(MISC_FTS_OUT)/*., o os)
- diff -Nur uClibc-0.9.32-rc3/libc/misc/Makefile.in uClibc/libc/misc/Makefile.in
- --- uClibc-0.9.32-rc3/libc/misc/Makefile.in 2011-03-16 20:11:13.000000000 +0100
- +++ uClibc/libc/misc/Makefile.in 2011-04-26 16:18:21.767661585 +0200
- @@ -16,6 +16,7 @@
- include $(top_srcdir)libc/misc/file/Makefile.in
- include $(top_srcdir)libc/misc/fnmatch/Makefile.in
- include $(top_srcdir)libc/misc/ftw/Makefile.in
- +include $(top_srcdir)libc/misc/fts/Makefile.in
- include $(top_srcdir)libc/misc/glob/Makefile.in
- include $(top_srcdir)libc/misc/gnu/Makefile.in
- include $(top_srcdir)libc/misc/internals/Makefile.in
- diff -Nur uClibc-0.9.32-rc3/libc/stdlib/malloc/heap.h uClibc/libc/stdlib/malloc/heap.h
- --- uClibc-0.9.32-rc3/libc/stdlib/malloc/heap.h 2011-03-16 20:11:13.000000000 +0100
- +++ uClibc/libc/stdlib/malloc/heap.h 2011-04-26 16:18:21.888707940 +0200
- @@ -29,8 +29,10 @@
- /* The heap allocates in multiples of, and aligned to, HEAP_GRANULARITY.
- HEAP_GRANULARITY must be a power of 2. Malloc depends on this being the
- same as MALLOC_ALIGNMENT. */
- -#define HEAP_GRANULARITY_TYPE double __attribute_aligned__ (sizeof (size_t))
- -#define HEAP_GRANULARITY (__alignof__ (HEAP_GRANULARITY_TYPE))
- +#define HEAP_GRANULARITY_TYPE double __attribute_aligned__ (HEAP_GRANULARITY)
- +#define HEAP_GRANULARITY \
- + (__alignof__ (double) > sizeof (size_t) ? __alignof__ (double) : sizeof (size_t))
- +
-
-
- /* The HEAP_INIT macro can be used as a static initializer for a heap
- diff -Nur uClibc-0.9.32-rc3/libc/stdlib/malloc/malloc.h uClibc/libc/stdlib/malloc/malloc.h
- --- uClibc-0.9.32-rc3/libc/stdlib/malloc/malloc.h 2011-03-16 20:11:13.000000000 +0100
- +++ uClibc/libc/stdlib/malloc/malloc.h 2011-04-26 16:18:21.888707940 +0200
- @@ -17,7 +17,7 @@
- alignment can be a significant win on targets like m68k and Coldfire,
- where __alignof__(double) == 2. */
- #define MALLOC_ALIGNMENT \
- - __alignof__ (double __attribute_aligned__ (sizeof (size_t)))
- + (__alignof__ (double) > sizeof (size_t) ? __alignof__ (double) : sizeof (size_t))
-
- /* The system pagesize... */
- extern size_t __pagesize;
- diff -Nur uClibc-0.9.32-rc3/libc/sysdeps/linux/common/lutimes.c uClibc/libc/sysdeps/linux/common/lutimes.c
- --- uClibc-0.9.32-rc3/libc/sysdeps/linux/common/lutimes.c 2011-03-16 20:11:13.000000000 +0100
- +++ uClibc/libc/sysdeps/linux/common/lutimes.c 2011-04-26 16:18:22.008914246 +0200
- @@ -12,7 +12,7 @@
-
- #ifdef __NR_lutimes
- _syscall2(int, lutimes, const char *, file, const struct timeval *, tvp)
- -#else
- +#elif defined __NR_utimensat
- #include <sys/time.h>
- #include <fcntl.h>
-
- diff -Nur uClibc-0.9.32-rc3/libc/sysdeps/linux/common/Makefile.in uClibc/libc/sysdeps/linux/common/Makefile.in
- --- uClibc-0.9.32-rc3/libc/sysdeps/linux/common/Makefile.in 2011-03-16 20:11:13.000000000 +0100
- +++ uClibc/libc/sysdeps/linux/common/Makefile.in 2011-04-26 16:18:21.927829410 +0200
- @@ -15,7 +15,9 @@
- CSRC-y := $(filter-out llseek.c $(CSRC_LFS),$(CSRC-y))
- CSRC-$(UCLIBC_HAS_LFS) += llseek.c $(CSRC_LFS)
-
- -CSRC-$(if $(or $(UCLIBC_HAS_SSP),$(UCLIBC_HAS_FORTIFY)),y) += ssp.c
- +ifneq ($(UCLIBC_HAS_SSP)$(UCLIBC_HAS_FORTIFY),)
- +CSRC-y += ssp.c
- +endif
- CSRC-$(UCLIBC_LINUX_MODULE_24) += create_module.c query_module.c \
- get_kernel_syms.c
- # we need these internally: fstatfs.c statfs.c
- @@ -25,7 +27,9 @@
- sendfile64.c sendfile.c setfsgid.c setfsuid.c setresuid.c \
- splice.c vmsplice.c tee.c signalfd.c swapoff.c swapon.c \
- sync_file_range.c sysctl.c sysinfo.c timerfd.c uselib.c vhangup.c
- -CSRC-$(if $(and $(UCLIBC_LINUX_SPECIFIC),$(UCLIBC_HAS_THREADS_NATIVE)),y) += madvise.c
- +ifeq ($(UCLIBC_LINUX_SPECIFIC)$(UCLIBC_HAS_THREADS_NATIVE),yy)
- +CSRC-y += madvise.c
- +endif
- ifeq ($(UCLIBC_HAS_THREADS_NATIVE),y)
- CSRC- += fork.c getpid.c raise.c open.c close.c read.c write.c
- CSRC- += $(if $(findstring =arm=,=$(TARGET_ARCH)=),vfork.c)
- diff -Nur uClibc-0.9.32-rc3/libc/sysdeps/linux/common/stubs.c uClibc/libc/sysdeps/linux/common/stubs.c
- --- uClibc-0.9.32-rc3/libc/sysdeps/linux/common/stubs.c 2011-03-16 20:11:13.000000000 +0100
- +++ uClibc/libc/sysdeps/linux/common/stubs.c 2011-04-26 16:18:22.038918529 +0200
- @@ -172,6 +172,14 @@
- make_stub(umount2)
- #endif
-
- +#ifndef __NR_utimensat
- +make_stub(futimens)
- +make_stub(utimensat)
- +# ifndef __NR_lutimes
- +make_stub(lutimes)
- +# endif
- +#endif
- +
- #ifndef __NR_vmsplice
- make_stub(vmsplice)
- #endif
- diff -Nur uClibc-0.9.32-rc3/libc/sysdeps/linux/cris/Makefile.arch uClibc/libc/sysdeps/linux/cris/Makefile.arch
- --- uClibc-0.9.32-rc3/libc/sysdeps/linux/cris/Makefile.arch 2011-03-16 20:11:13.000000000 +0100
- +++ uClibc/libc/sysdeps/linux/cris/Makefile.arch 2011-04-26 16:18:22.048914220 +0200
- @@ -7,7 +7,7 @@
-
- CSRC := __init_brk.c brk.c sbrk.c
-
- -SSRC := setjmp.S __longjmp.S clone.S sysdep.S syscall.S
- +SSRC := setjmp.S __longjmp.S clone.S sysdep.S syscall.S vfork.S
- ifeq ($(UNIFIED_SYSCALL),y)
- SSRC += __uClibc_syscall.S
- endif
- diff -Nur uClibc-0.9.32-rc3/libc/sysdeps/linux/cris/vfork.S uClibc/libc/sysdeps/linux/cris/vfork.S
- --- uClibc-0.9.32-rc3/libc/sysdeps/linux/cris/vfork.S 1970-01-01 01:00:00.000000000 +0100
- +++ uClibc/libc/sysdeps/linux/cris/vfork.S 2011-04-26 16:18:22.058385770 +0200
- @@ -0,0 +1,30 @@
- +/*-
- + * Copyright (c) 2011
- + * Thorsten Glaser <tg@freewrt.org>
- + *
- + * This file is available either under the terms and conditions of
- + * the MirOS Licence, or the same terms as klibc or uClibc.
- + */
- +
- +#include "sysdep.h"
- +
- + .syntax no_register_prefix
- +
- +/*
- + * vfork is special, but PSEUDO() would probably work were it not broken;
- + * there must be nothing at all on the stack above the stack frame of the
- + * enclosing function
- + */
- +
- +ENTRY(__vfork)
- + movu.w __NR_vfork,$r9
- + break 13
- + cmps.w -4096,$r10
- + bhs 0f
- + nop
- + Ret
- + nop
- +PSEUDO_END(__vfork)
- +
- +weak_alias(__vfork,vfork)
- +libc_hidden_weak(vfork)
- diff -Nur uClibc-0.9.32-rc3/libc/sysdeps/linux/Makefile.commonarch uClibc/libc/sysdeps/linux/Makefile.commonarch
- --- uClibc-0.9.32-rc3/libc/sysdeps/linux/Makefile.commonarch 2011-03-16 20:11:13.000000000 +0100
- +++ uClibc/libc/sysdeps/linux/Makefile.commonarch 2011-04-26 16:18:21.917874257 +0200
- @@ -36,6 +36,6 @@
- headers-y += $(ARCH_HEADERS_OUT)
- headers_clean-y += HEADERCLEAN_$(subst $(top_builddir),,$(ARCH_OUT))
- HEADERCLEAN_$(subst $(top_builddir),,$(ARCH_OUT)):
- - $(RM) $(ARCH_HEADERS_OUT)
- + $(do_rm) $(ARCH_HEADERS_OUT)
-
- endif
- 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
- --- uClibc-0.9.32-rc3/libc/sysdeps/linux/sparc/soft-fp/sfp-machine.h 2011-03-16 20:11:13.000000000 +0100
- +++ uClibc/libc/sysdeps/linux/sparc/soft-fp/sfp-machine.h 2011-04-26 16:18:22.198914568 +0200
- @@ -187,6 +187,7 @@
-
- #define _FP_DECL_EX fpu_control_t _fcw
-
- +#ifdef __UCLIBC_HAS_FPU__
- #define FP_INIT_ROUNDMODE \
- do { \
- _FPU_GETCW(_fcw); \
- @@ -211,3 +212,4 @@
- else \
- ___Q_simulate_exceptions (_fex); \
- } while (0)
- +#endif
- diff -Nur uClibc-0.9.32-rc3/libubacktrace/backtrace.c uClibc/libubacktrace/backtrace.c
- --- uClibc-0.9.32-rc3/libubacktrace/backtrace.c 2011-03-16 20:11:13.000000000 +0100
- +++ uClibc/libubacktrace/backtrace.c 2011-04-26 16:18:22.608067667 +0200
- @@ -4,16 +4,81 @@
- * User application that wants to use backtrace needs to be
- * compiled with -fexceptions option and -rdynamic to get full
- * symbols printed.
- -
- - * Copyright (C) 2010 STMicroelectronics Ltd
- + *
- + * Copyright (C) 2009, 2010 STMicroelectronics Ltd.
- + *
- + * Author(s): Giuseppe Cavallaro <peppe.cavallaro@st.com>
- + * - Initial implementation for glibc
- + *
- * Author(s): Carmelo Amoroso <carmelo.amoroso@st.com>
- + * - Reworked for uClibc
- + * - use dlsym/dlopen from libdl
- + * - rewrite initialisation to not use libc_once
- + * - make it available in static link too
- *
- * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
- *
- */
- -#error "Arch specific implementation must be provided to properly work"
- -int backtrace (void **array, int size)
- +
- +#include <execinfo.h>
- +#include <dlfcn.h>
- +#include <stdlib.h>
- +#include <unwind.h>
- +#include <assert.h>
- +#include <stdio.h>
- +
- +struct trace_arg
- {
- - return -1;
- + void **array;
- + int cnt, size;
- +};
- +
- +static _Unwind_Reason_Code (*unwind_backtrace) (_Unwind_Trace_Fn, void *);
- +static _Unwind_Ptr (*unwind_getip) (struct _Unwind_Context *);
- +
- +static void backtrace_init (void)
- +{
- + void *handle = dlopen ("libgcc_s.so.1", RTLD_LAZY);
- +
- + if (handle == NULL
- + || ((unwind_backtrace = dlsym (handle, "_Unwind_Backtrace")) == NULL)
- + || ((unwind_getip = dlsym (handle, "_Unwind_GetIP")) == NULL)) {
- + printf("libgcc_s.so.1 must be installed for backtrace to work\n");
- + abort();
- + }
- }
-
- +static _Unwind_Reason_Code
- +backtrace_helper (struct _Unwind_Context *ctx, void *a)
- +{
- + struct trace_arg *arg = a;
- +
- + assert (unwind_getip != NULL);
- +
- + /* We are first called with address in the __backtrace function. Skip it. */
- + if (arg->cnt != -1)
- + arg->array[arg->cnt] = (void *) unwind_getip (ctx);
- + if (++arg->cnt == arg->size)
- + return _URC_END_OF_STACK;
- + return _URC_NO_REASON;
- +}
- +
- +/*
- + * Perform stack unwinding by using the _Unwind_Backtrace.
- + *
- + * User application that wants to use backtrace needs to be
- + * compiled with -fexceptions option and -rdynamic to get full
- + * symbols printed.
- + */
- +int backtrace (void **array, int size)
- +{
- + struct trace_arg arg = { .array = array, .size = size, .cnt = -1 };
- +
- + if (unwind_backtrace == NULL)
- + backtrace_init();
- +
- + if (size >= 1)
- + unwind_backtrace (backtrace_helper, &arg);
- +
- + return arg.cnt != -1 ? arg.cnt : 0;
- +}
- diff -Nur uClibc-0.9.32-rc3/libubacktrace/Makefile.in uClibc/libubacktrace/Makefile.in
- --- uClibc-0.9.32-rc3/libubacktrace/Makefile.in 2011-03-16 20:11:13.000000000 +0100
- +++ uClibc/libubacktrace/Makefile.in 2011-04-26 16:18:22.608067667 +0200
- @@ -18,29 +18,16 @@
-
- libubacktrace_DIR := $(top_srcdir)libubacktrace
- libubacktrace_OUT := $(top_builddir)libubacktrace
- -libubacktrace_ARCH_DIR := $(libubacktrace_DIR)/sysdeps/$(TARGET_ARCH)
- -libubacktrace_ARCH_OUT := $(libubacktrace_OUT)/sysdeps/$(TARGET_ARCH)
- -
- --include $(libubacktrace_ARCH_DIR)/Makefile.arch
-
- libubacktrace_SRC-y :=
- libubacktrace_SRC-$(UCLIBC_HAS_BACKTRACE) := backtrace.c backtracesyms.c backtracesymsfd.c
-
- -CFLAGS-libubacktrace/sysdeps/$(TARGET_ARCH)/ := $(CFLAGS-libubacktrace)
- -
- -# remove generic sources, if arch specific version is present
- -ifneq ($(strip $(libubacktrace_ARCH_SRC-y)),)
- -libubacktrace_SRC-y := $(filter-out $(notdir $(libubacktrace_ARCH_SRC-y)),$(libubacktrace_SRC-y))
- -libubacktrace_ARCH_SRC := $(addprefix $(libubacktrace_ARCH_DIR)/,$(libubacktrace_ARCH_SRC-y))
- -libubacktrace_ARCH_OBJ := $(patsubst $(libubacktrace_ARCH_DIR)/%.c,$(libubacktrace_ARCH_OUT)/%.o,$(libubacktrace_ARCH_SRC))
- -endif
- -
- +# -fexections is required for backtrace to work using dwarf2
- +CFLAGS-backtrace.c := -fexceptions
-
- -libubacktrace_SRC := $(addprefix $(libubacktrace_DIR)/,$(libubacktrace_SRC-y))
- -libubacktrace_OBJ := $(patsubst $(libubacktrace_DIR)/%.c,$(libubacktrace_OUT)/%.o,$(libubacktrace_SRC))
-
- -libubacktrace_SRCS := $(libubacktrace_SRC) $(libubacktrace_ARCH_SRC)
- -libubacktrace_OBJS := $(libubacktrace_OBJ) $(libubacktrace_ARCH_OBJ)
- +libubacktrace_SRCS := $(addprefix $(libubacktrace_DIR)/,$(libubacktrace_SRC-y))
- +libubacktrace_OBJS := $(patsubst $(libubacktrace_DIR)/%.c,$(libubacktrace_OUT)/%.o,$(libubacktrace_SRCS))
-
- ifeq ($(DOPIC),y)
- libubacktrace-a-y := $(libubacktrace_OBJS:.o=.os)
- diff -Nur uClibc-0.9.32-rc3/libubacktrace/sysdeps/sh/backtrace.c uClibc/libubacktrace/sysdeps/sh/backtrace.c
- --- uClibc-0.9.32-rc3/libubacktrace/sysdeps/sh/backtrace.c 2011-03-16 20:11:13.000000000 +0100
- +++ uClibc/libubacktrace/sysdeps/sh/backtrace.c 1970-01-01 01:00:00.000000000 +0100
- @@ -1,84 +0,0 @@
- -/*
- - * Perform stack unwinding by using the _Unwind_Backtrace.
- - *
- - * User application that wants to use backtrace needs to be
- - * compiled with -fexceptions option and -rdynamic to get full
- - * symbols printed.
- - *
- - * Copyright (C) 2009, 2010 STMicroelectronics Ltd.
- - *
- - * Author(s): Giuseppe Cavallaro <peppe.cavallaro@st.com>
- - * - Initial implementation for glibc
- - *
- - * Author(s): Carmelo Amoroso <carmelo.amoroso@st.com>
- - * - Reworked for uClibc
- - * - use dlsym/dlopen from libdl
- - * - rewrite initialisation to not use libc_once
- - * - make it available in static link too
- - *
- - * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
- - *
- - */
- -
- -#include <execinfo.h>
- -#include <dlfcn.h>
- -#include <stdlib.h>
- -#include <unwind.h>
- -#include <assert.h>
- -#include <stdio.h>
- -
- -struct trace_arg
- -{
- - void **array;
- - int cnt, size;
- -};
- -
- -static _Unwind_Reason_Code (*unwind_backtrace) (_Unwind_Trace_Fn, void *);
- -static _Unwind_Ptr (*unwind_getip) (struct _Unwind_Context *);
- -
- -static void backtrace_init (void)
- -{
- - void *handle = dlopen ("libgcc_s.so.1", RTLD_LAZY);
- -
- - if (handle == NULL
- - || ((unwind_backtrace = dlsym (handle, "_Unwind_Backtrace")) == NULL)
- - || ((unwind_getip = dlsym (handle, "_Unwind_GetIP")) == NULL)) {
- - printf("libgcc_s.so.1 must be installed for backtrace to work\n");
- - abort();
- - }
- -}
- -
- -static _Unwind_Reason_Code
- -backtrace_helper (struct _Unwind_Context *ctx, void *a)
- -{
- - struct trace_arg *arg = a;
- -
- - assert (unwind_getip != NULL);
- -
- - /* We are first called with address in the __backtrace function. Skip it. */
- - if (arg->cnt != -1)
- - arg->array[arg->cnt] = (void *) unwind_getip (ctx);
- - if (++arg->cnt == arg->size)
- - return _URC_END_OF_STACK;
- - return _URC_NO_REASON;
- -}
- -
- -/*
- - * Perform stack unwinding by using the _Unwind_Backtrace.
- - *
- - * User application that wants to use backtrace needs to be
- - * compiled with -fexceptions option and -rdynamic to get full
- - * symbols printed.
- - */
- -int backtrace (void **array, int size)
- -{
- - struct trace_arg arg = { .array = array, .size = size, .cnt = -1 };
- -
- - if (unwind_backtrace == NULL)
- - backtrace_init();
- -
- - if (size >= 1)
- - unwind_backtrace (backtrace_helper, &arg);
- -
- - return arg.cnt != -1 ? arg.cnt : 0;
- -}
- diff -Nur uClibc-0.9.32-rc3/libubacktrace/sysdeps/sh/Makefile.arch uClibc/libubacktrace/sysdeps/sh/Makefile.arch
- --- uClibc-0.9.32-rc3/libubacktrace/sysdeps/sh/Makefile.arch 2011-03-16 20:11:13.000000000 +0100
- +++ uClibc/libubacktrace/sysdeps/sh/Makefile.arch 1970-01-01 01:00:00.000000000 +0100
- @@ -1,12 +0,0 @@
- -# Makefile for uClibc (sh/libubacktrace)
- -#
- -# Copyright (C) 2010 STMicroelectronics Ltd
- -# Author: Carmelo Amoroso <carmelo.amoroso@st.com>
- -
- -# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
- -#
- -
- -libubacktrace_ARCH_SRC-y := backtrace.c
- -
- -# -fexections is required for backtrace to work using dwarf2
- -CFLAGS-backtrace.c := -fexceptions
- diff -Nur uClibc-0.9.32-rc3/Makefile.in uClibc/Makefile.in
- --- uClibc-0.9.32-rc3/Makefile.in 2011-03-16 20:11:13.000000000 +0100
- +++ uClibc/Makefile.in 2011-04-26 16:18:21.697662740 +0200
- @@ -239,6 +239,7 @@
- tgmath.h \
- bits/math*.h
- HEADERS_RM-$(findstring y,$(UCLIBC_HAS_FTW)$(UCLIBC_HAS_NFTW)) += ftw.h
- +HEADERS_RM-$(UCLIBC_HAS_FTS) += fts.h
- HEADERS_RM-$(UCLIBC_HAS_GETTEXT_AWARENESS) += libintl.h
- HEADERS_RM-$(UCLIBC_HAS_GLIBC_CUSTOM_PRINTF) += printf.h
- HEADERS_RM-$(UCLIBC_HAS_GLOB) += glob.h
- diff -Nur uClibc-0.9.32-rc3/Rules.mak uClibc/Rules.mak
- --- uClibc-0.9.32-rc3/Rules.mak 2011-03-16 20:11:13.000000000 +0100
- +++ uClibc/Rules.mak 2011-04-26 16:18:21.697662740 +0200
- @@ -531,7 +531,7 @@
- export CC_FLAG_NO_ASNEEDED:=-Wl,$(LD_FLAG_NO_ASNEEDED)
- endif
- endif
- -link.asneeded = $(if $(and $(CC_FLAG_ASNEEDED),$(CC_FLAG_NO_ASNEEDED)),$(CC_FLAG_ASNEEDED) $(1) $(CC_FLAG_NO_ASNEEDED))
- +link.asneeded = $(if $(findstring yy,$(CC_FLAG_ASNEEDED)$(CC_FLAG_NO_ASNEEDED)),$(CC_FLAG_ASNEEDED) $(1) $(CC_FLAG_NO_ASNEEDED))
-
- # Check for AS_NEEDED support in linker script (binutils>=2.16.1 has it)
- ifndef ASNEEDED
- diff -Nur uClibc-0.9.32-rc3/test/tls/Makefile.in uClibc/test/tls/Makefile.in
- --- uClibc-0.9.32-rc3/test/tls/Makefile.in 2011-03-16 20:11:13.000000000 +0100
- +++ uClibc/test/tls/Makefile.in 2011-04-26 16:18:22.827742938 +0200
- @@ -140,7 +140,6 @@
- $(LDFLAGS_tst-tlsmod18a.so)
- tst-tls-at-ctor: tst-tlsmod-at-ctor.so
-
- -RET_tst-tls13 := 1
- ifeq ($(TARGET_ARCH),mips)
- RET_tst-tls15 := 1
- endif
- diff -Nur uClibc-0.9.32-rc3/test/tls/tst-tls13.c uClibc/test/tls/tst-tls13.c
- --- uClibc-0.9.32-rc3/test/tls/tst-tls13.c 2011-03-16 20:11:13.000000000 +0100
- +++ uClibc/test/tls/tst-tls13.c 2011-04-26 16:18:22.837818558 +0200
- @@ -26,5 +26,5 @@
- }
-
- #define TEST_FUNCTION do_test ()
- -#define TIMEOUT 3
- +#define TIMEOUT 20
- #include "../test-skeleton.c"
- diff -Nur uClibc-0.9.32-rc3/utils/ldd.c uClibc/utils/ldd.c
- --- uClibc-0.9.32-rc3/utils/ldd.c 2011-03-16 20:11:13.000000000 +0100
- +++ uClibc/utils/ldd.c 2011-04-26 16:18:22.888166105 +0200
- @@ -553,7 +553,7 @@
- interp_name = strdup(s);
- interp_dir = strdup(s);
- tmp = strrchr(interp_dir, '/');
- - if (*tmp)
- + if (tmp)
- *tmp = '\0';
- else {
- free(interp_dir);
|