Compare commits

..

58 Commits
4.11.1 ... 4.11

Author SHA1 Message Date
Christian Mauderer
051778e9d6 imfs: Fix index underrun when extending empty file
Currently the following sequence causes a endless loop when extending an
IMFS file:

- Create a file with zero length and close it.
- Make sure nearly no allocatable memory is left.
- Open the file and write enough data into it that more than the
  remaining memory will be used.

In that case when extending the IMFS file, the file currently need zero
blocks. If allocating enough new blocks fails, the already allocated new
blocks will be freed again.

The comparison of block>=old_blocks that has been used prior to this
patch compared two unsigned numbers. If old_blocks was zero, the
comparison of these two numbers always evaluated to true.

This patch frees the last block in a separate step to avoid this
problem.

Note: This patch is a backport of
43119193ef from RTEMS master. It only
contains the bugfix. Adding a test case has been skipped because that
part of the patch didn't apply without problems and is not really
relevant for fixing the bug.

Fixes #2353
2022-04-07 10:45:12 +02:00
Thanassis Tsiodras
63c6b06fd1 bsps/sparc: Fix global construction/destruction
The

  KEEP (*(SORT(.ctors.*)))
  KEEP (*(.ctors))

cannot be simplified to

  KEEP (*(SORT(.ctors*)))

since

  .ctors < .ctors.*

in lexicographical order.

See spglobalcon02 test case.

Close #3319.
2021-08-12 14:47:59 +02:00
Daniel Hellstrom
a100457c7d leon,gr1553b: improve init check
Check in init3 not needed since same data is already checked in init2
stage. Adds an extra check that the APB register space is available before
accessing it.

Closes #2331
2020-10-01 11:35:03 +10:00
Chris Johns
55d9d8c552 libmisc/shell: Updating joel script handling fixes from RTEMS 5
Updates #3877
2020-04-14 18:48:32 +10:00
Chris Johns
4d906d6af1 libmisc/shell: Fix the handling of joel scripts in telnet
- Fix the passing of std[in/out] to child threads
- Fix deleting of managed memory in the key destructor
- Only set the key in the main loop thread
- Only allocate a shell env outside of the main loop
- Fix memory leak if the task start fails
- Remove error level from shell env, it cannot be returned this way. Add
  exit_code but the API is broken so it cannot be returned.

Closes #3877
2020-02-19 19:05:54 +11:00
Chris Johns
fe09d8d4d3 libcsupport/newlib: Call newlib's __sinit to force reent initialisation
- Newlib overtites any FILE pointers set in stdin, stdout or stderr.

Closes #3870
2020-02-19 19:01:08 +11:00
Jonathan Brandmeyer
33c82ddba1 shell: Correct argument order of mfill
Close #3722.

(cherry picked from commit 2e8a66d13f)
2019-03-14 09:57:40 -04:00
Sebastian Huber
dc6bd8bb66 score: Fix ISR enable in _Thread_Dispatch_enable()
This bug had probably no effect since the interrupt enable is idempotent
on all CPU ports.

Close #3497.
2018-08-20 08:40:24 +02:00
Sebastian Huber
3abc731b22 rfs: Remove erroneous call of rtems_disk_release()
The function rtems_rfs_buffer_sync() erroneously calls
rtems_disk_release(). This screws up the reference counting of the disk.

Close #3494.
2018-08-10 06:57:10 +02:00
Sebastian Huber
d4165e7173 sptests/sp36: Remove obsolete test program
It tests the (never really working) strict order mutex option.

Update #3406.
2018-06-19 07:58:13 +02:00
Chris Johns
c3353ae565 cpukit/mttpd: Add a callback to generate a per file HTTP etag.
Closes #3324
2018-03-08 15:34:15 +11:00
Chris Johns
7093cb5e5d libtest/dl01: Add dlerror tests.
Update #2747
2018-02-08 14:21:13 +11:00
Patrick Gauvin
5812a26eeb Update dlerror usage
Handles possible NULL return value

Updates #2747
2018-02-08 14:21:13 +11:00
Patrick Gauvin
dc746b50ca libdl: Fix dlerror return type
POSIX specifies char *, not const char *

Updates #2747
2018-02-08 14:21:13 +11:00
Patrick Gauvin
a346408e4e libdl: dlerror return NULL when no error
Updates #2747
2018-02-08 14:21:13 +11:00
Patrick Gauvin
a2a9751823 libdl: Clear error between dlerror invocations
Updates #2747
2018-02-08 14:21:13 +11:00
Chris Johns
1a304307a2 testsuites/libtest: Set EXENT to .exe so executable are correctly named.
The configure order effects how it works.

Close #3297
2018-02-08 14:20:26 +11:00
Christian Mauderer
d438427cbe dosfs: Allow creating a file with similar name.
If there is already a file with a long file name it isn't possible to
create a second file which has a name that ends on the first files name
(for example ets.beam and sets.beam). This patch fixes that.

Close #3258.
2017-12-07 08:04:11 +01:00
Christian Mauderer
004a63efef dosfs: Fix files with same name as volume name.
Take care that a file in the root directory with the same name as the
volume name can be found.

Close #3257.
2017-12-05 08:02:42 +01:00
Sebastian Huber
c139a70597 posix: Fix aio_cancel()
Close #3164.
2017-10-04 09:26:40 +02:00
Sebastian Huber
1a21831b3c i2c: Fix EEPROM driver program timeout handling
The RTEMS_MILLISECONDS_TO_TICKS() macro doesn't round up. Do not use it
to calculate the program timeout in ticks. Check program done condition
after the timeout check to account for pre-emptions.

Close #3162.
2017-10-02 13:44:36 +02:00
Sebastian Huber
8ca15e26ba i2c: Send MSB of address first for EEPROMs
Close #3161.
2017-10-02 13:44:32 +02:00
Sebastian Huber
a3199d91f3 dosfs: Fix fat_file_update()
Do not update the non-existant meta-data of the root directory.

Close #2944.
2017-09-06 14:40:38 +02:00
Sebastian Huber
a76c31e13d dosfs: Fix find name next entry preparation
Close #2964.
2017-09-06 14:09:11 +02:00
Sebastian Huber
e1c3dc0909 dosfs: Fix msdos_dir_read()
Set a proper name buffer length for each converter invocation.

Close #2987.
2017-09-06 13:24:34 +02:00
Chris Johns
2ed53cb982 testsuite/dl: Add C++ by default for DL tests which use C++.
- Add AM C++ support to the testsuite configure.ac script.
- Fix the dependences in the  DL tests.

Closes #3024.
2017-08-23 09:48:56 +10:00
Chris Johns
89fd08eae6 libmisc/shell: Make some internal shell functions public.
- Add 'rtems_shell_init_environment()' so a user can create the
  shell environment without needing to run a shell.
- Move 'rtems_shell_lookup_topic', 'rtems_shell_can_see_cmd',
  and 'rtems_shell_execute_cmd' from the internal interface to
  the public interface.

Closes #3104.
2017-08-23 09:48:56 +10:00
Sebastian Huber
492c95eee6 confdefs: Fix POSIX keys configuration
Remove the OBJECTS_UNLIMITED_OBJECTS flag for the memory size
configuration.

Close #3105.
2017-08-22 08:03:10 +02:00
Sebastian Huber
7d097c5c69 arm: Validate IT[7:0] bit field of PSR
Close #3093.
2017-08-10 09:24:26 +02:00
Sebastian Huber
5cc276e7c1 arm: Fix CPU context validation for Cortex-R4
Do not touch the FPSCR[QC] bit since this is DNM/RAZ on Cortex-R4.

Close #3092.
2017-08-10 08:21:04 +02:00
Sebastian Huber
7e91901303 arm: Fix ARMv7-M interrupt processing
Right after a "msr basepri_max, %[basepri]" instruction an interrupt
service may still take place (observed at least on Cortex-M7).  However,
pendable service calls that are activated during this interrupt service
may be delayed until interrupts are enable again.  The
_ARMV7M_Pendable_service_call() did not check that a thread dispatch is
allowed.  Move this test from _ARMV7M_Interrupt_service_leave() to
_ARMV7M_Pendable_service_call().

Close #3060.
2017-07-07 13:27:24 +02:00
Sebastian Huber
09cbe713ff bsps/arm: Fix bit field offset in GIC support
Close #3002.
2017-05-11 09:57:53 +02:00
Chris Johns
d2e31f70c1 libdl: Back port C++ exception throw and catch from 4.12.
Closes #2956.
2017-04-04 13:26:01 +10:00
Sebastian Huber
d51538bdbe dosfs: Fix file name search
Do not use our long file name entry count to optimize the file name
search. The Unicode comparison must be taken into account.

Close #2939.
2017-03-21 16:15:25 +01:00
Sebastian Huber
89164c67bc dosfs: Fix race condition msdos_dir_read()
Obtain file system instance lock before member access.

Close #2937.
2017-03-21 16:15:21 +01:00
Sebastian Huber
4c4869f483 dosfs: Rename fat_entries to lfn_entries
The name "fat_entries" for long file name directory entries is quite
misleading.
2017-03-21 16:15:17 +01:00
Sebastian Huber
7011f26061 dosfs: Fix long file name padding
Close #2934.
2017-03-21 16:15:11 +01:00
Sebastian Huber
49eb6061ec dosfs: msdos_filename_utf8_to_short_name_for_save
Simplify.
2017-03-21 16:15:09 +01:00
Sebastian Huber
5ed41a6d82 dosfs: Fix msdos_add_file()
Make sure that long file names work accross cluster boundaries.

Close #2929.
2017-03-21 16:15:04 +01:00
Sebastian Huber
58e8131184 dosfs: Simplify msdos_add_file()
Update #2929.
2017-03-21 16:15:00 +01:00
Sebastian Huber
565b1a57b7 dosfs: Add and use msdos_lfn_checksum()
Update #2929.
2017-03-21 16:14:59 +01:00
Sebastian Huber
ad3a744ac4 dosfs: Simplify fat_file_open()
Update #2929.
2017-03-21 16:14:57 +01:00
Sebastian Huber
201f3797b3 dosfs: Simplify msdos_creat_node()
Update #2929.
2017-03-21 16:14:53 +01:00
Sebastian Huber
c38f1fcf8f dosfs: Fix fat_file_write()
Remove forced overwrite which leads to file data corruption.  The logic
to determine a forced overwrite was fundamentally broken.  For simplity,
disable this feature.

Close #2622.
2017-03-21 16:14:44 +01:00
Sebastian Huber
21d7154b07 dosfs: Fix msdos_utf8_normalize_and_fold()
It is all right in case the result uses the full destination buffer.
Without this fix the handling of a maximum 8.3 short file name is
broken.

Close #2928.
2017-03-21 16:14:37 +01:00
Sebastian Huber
f08c71339c libio: Fix deadlock in location management
Perform a context-dependent deferred location release to avoid a
deadlock on the file system instance locks, for example during a
chdir().

Close #2936.
2017-03-21 16:13:11 +01:00
Chris Johns
2ea436a167 Config (.cfg) files are only valid if deeper than 5.
Closes #2827.
2017-03-21 14:38:59 +11:00
Sebastian Huber
a27128c5dc termios: Fix infinite loop in receive path
In canonical mode, the raw input buffer or the canonical buffer may
overflow without an end of line.  Avoid an infinite loop in this case.

Update #2915.
2017-02-28 09:55:58 +01:00
Sebastian Huber
0e8d205559 termios: Protect raw input buffer with device lock
Use the device lock to protect the raw input buffer management, e.g.
tail, head and buffer content updates.

Update #2914.
2017-02-28 09:55:55 +01:00
Sebastian Huber
35a3d81581 termios: Simplify rtems_termios_read_tty()
Remove dead code.

Update #2914.
2017-02-28 09:53:21 +01:00
Sebastian Huber
17f81ee3cb dosfs: Fix FAT32 formatter
The second FAT entry contains a bit to indicate if the FAT32 filesystem
is not dirty and a bit to indicate if there was no IO error.  Set both
bits for a fresh filesystem.  This prevents a warning if mounted on
Windows.

Update #2913.
2017-02-28 09:50:58 +01:00
Sebastian Huber
6ec60de37d dosfs: Directories should have a file size of 0
Update #2755.
2017-02-28 09:50:53 +01:00
Nick Withers
7e0a02a70f Remove old CVS keywords
Close #2388.
2017-02-15 14:53:07 +01:00
Sudarshan Rajagopalan
5b5ef4e479 Fix exception handler for supporting FPU
Close #2401.
2017-02-15 14:18:53 +01:00
Sebastian Huber
04684cbc43 dosfs: Fix msdos_find_file_in_directory()
For a filename match the entry must match without anything remaining.

Update #2908.
2017-02-14 08:09:57 +01:00
Sebastian Huber
69ae534cbb Change version to 4.11.1.99
Update #2886.
2017-01-26 08:31:50 +01:00
Christian Spindeldreier
af9143fba5 GRETH: Interrupt Handler Uses Wrong Events
closes #2796.
2017-01-12 09:38:38 -06:00
Joel Sherrill
d46a65d052 Remove texinfo format documentation. Replaced by Sphinx formatted documentation.
updates #2812.
2017-01-11 12:08:15 -06:00
471 changed files with 6141 additions and 147229 deletions

View File

@@ -14,7 +14,7 @@ EXTRA_DIST += config-ml.in
EXTRA_DIST += ampolish3
dist-hook:
@files=`(cd $(srcdir); find doc cpukit c testsuites tools \
@files=`(cd $(srcdir); find cpukit c testsuites tools \
-name configure.ac -print | sed 's,/configure.ac,,' | sort)`; \
for i in $$files; do \
if test -f $(distdir)/$$i/configure.ac; then : ; \

View File

@@ -54,15 +54,6 @@ rtems-$(rtems_version)/stamp.export.$(rtems_tag)$(TAG_SUFFIX):
rtems-$(rtems_version)$(TAG_SUFFIX).tar.bz2: rtems-$(rtems_version)/stamp.autofiles \
rtems-$(rtems_version)/excludes \
rtems-$(rtems_version)/TOOL_VERSIONS
cd rtems-$(rtems_version) ; \
touch doc/ada_user/ada_user.texi doc/bsp_howto/bsp_howto.texi \
doc/cpu_supplement/cpu_supplement.texi \
doc/develenv/develenv.texi doc/filesystem/filesystem.texi \
doc/networking/networking.texi \
doc/new_chapters/new_chapters.texi \
doc/porting/porting.texi doc/posix1003.1/posix1003_1.texi \
doc/posix_users/posix_users.texi doc/relnotes/relnotes.texi \
doc/started/started.texi doc/user/c_user.texi
tar -cj -X rtems-$(rtems_version)/excludes \
-f rtems-$(rtems_version)$(TAG_SUFFIX).tar.bz2 rtems-$(rtems_version)

View File

@@ -1,4 +1,4 @@
AC_DEFUN([RTEMS_VERSIONING],
m4_define([_RTEMS_VERSION],[4.10.99.0]))
m4_define([_RTEMS_VERSION],[4.11.1.99]))
m4_define([_RTEMS_API],[4.11])

View File

@@ -223,7 +223,6 @@ clean)
needles="$needles install-sh"
needles="$needles missing"
needles="$needles mdate-sh"
needles="$needles texinfo.tex"
fi
for j in $needles; do
files=`find . -name "$j" -print`

View File

@@ -1,4 +1,4 @@
AC_DEFUN([RTEMS_VERSIONING],
m4_define([_RTEMS_VERSION],[4.10.99.0]))
m4_define([_RTEMS_VERSION],[4.11.1.99]))
m4_define([_RTEMS_API],[4.11])

View File

@@ -43,7 +43,7 @@ extern "C" {
#define GIC_ID_TO_ONE_BIT_REG_BIT(id) (1U << ((id) & 0x1fU))
#define GIC_ID_TO_TWO_BITS_REG_INDEX(id) ((id) >> 4)
#define GIC_ID_TO_TWO_BITS_REG_OFFSET(id) ((id) & 0xfU)
#define GIC_ID_TO_TWO_BITS_REG_OFFSET(id) (((id) & 0xfU) << 1)
static inline bool gic_id_is_enabled(volatile gic_dist *dist, uint32_t id)
{

View File

@@ -191,6 +191,8 @@ static int gr1553_init2(struct drvmgr_dev *dev)
return DRVMGR_FAIL;
}
pnpinfo = &ambadev->info;
if ( pnpinfo->apb_slv == NULL )
return DRVMGR_EIO;
regs = (struct gr1553b_regs *)pnpinfo->apb_slv->start;
/* Stop IRQ */
@@ -227,9 +229,6 @@ static int gr1553_init3(struct drvmgr_dev *dev)
/* Get device information from AMBA PnP information */
ambadev = (struct amba_dev_info *)dev->businfo;
if ( ambadev == NULL ) {
return DRVMGR_FAIL;
}
pnpinfo = &ambadev->info;
regs = (struct gr1553b_regs *)pnpinfo->apb_slv->start;
@@ -257,6 +256,12 @@ static int gr1553_init3(struct drvmgr_dev *dev)
gr1553_list_add(&gr1553_rt_root, feat);
}
if ( priv->features == 0 ) {
/* no features in HW should never happen.. an I/O error? */
free(priv);
return DRVMGR_EIO;
}
return DRVMGR_OK;
}

View File

@@ -246,7 +246,7 @@ static void greth_interrupt (void *arg)
/* Send the event(s) */
if ( events )
rtems_event_send (greth->daemonTid, events);
rtems_bsdnet_event_send(greth->daemonTid, events);
}
static uint32_t read_mii(struct greth_softc *sc, uint32_t phy_addr, uint32_t reg_addr)

View File

@@ -87,11 +87,13 @@ SECTIONS
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors*)))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors*)))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
_rodata_start = . ;
*(.rodata*)

View File

@@ -30,10 +30,6 @@ RTEMS_ENABLE_MULTILIB
RTEMS_ENABLE_PARAVIRT
RTEMS_ENABLE_DRVMGR
AC_ARG_ENABLE([docs],
[AS_HELP_STRING([--enable-docs],[enable building documentation
(default:disabled)])])
## NOTES:
## * tools/build are host-native tools to be installed on the host.
## * tools/cpu are host-native or host-cross-target-tools
@@ -52,9 +48,6 @@ AS_IF([test $host != $build],[
RTEMS_HOST_CONFIG_SUBDIRS([tools/build])
])
AS_IF([test x"${enable_docs}" = x"yes"],
[RTEMS_BUILD_CONFIG_SUBDIRS([doc])])
AS_IF([test x"$enable_multilib" = x"yes"],[
RTEMS_TARGET_CONFIG_SUBDIRS([cpukit])
])

View File

@@ -90,7 +90,7 @@ include_rtems_rtl_HEADERS += libdl/dlfcn-shell.h
include_rtems_rtl_HEADERS += libdl/rtl.h libdl/rtl-allocator.h libdl/rtl-obj-fwd.h
include_rtems_rtl_HEADERS += libdl/rtl-fwd.h libdl/rtl-obj.h libdl/rtl-obj-cache.h
include_rtems_rtl_HEADERS += libdl/rtl-obj-comp.h libdl/rtl-unresolved.h
include_rtems_rtl_HEADERS += libdl/rtl-indirect-ptr.h libdl/rtl-sym.h
include_rtems_rtl_HEADERS += libdl/rtl-indirect-ptr.h libdl/rtl-sym.h libdl/rtl-trace.h
include_rtems_rtl_HEADERS += libdl/rap.h libdl/rap-shell.h
endif

View File

@@ -1,4 +1,4 @@
AC_DEFUN([RTEMS_VERSIONING],
m4_define([_RTEMS_VERSION],[4.10.99.0]))
m4_define([_RTEMS_VERSION],[4.11.1.99]))
m4_define([_RTEMS_API],[4.11])

View File

@@ -39,7 +39,7 @@ typedef struct {
uint32_t size;
uint16_t i2c_address_mask;
uint16_t i2c_address_shift;
rtems_interval program_timeout;
rtems_interval program_timeout_in_ticks;
} eeprom;
static uint16_t eeprom_i2c_addr(eeprom *dev, uint32_t off)
@@ -48,6 +48,23 @@ static uint16_t eeprom_i2c_addr(eeprom *dev, uint32_t off)
| ((off >> dev->i2c_address_shift) & dev->i2c_address_mask);
}
static void eeprom_set_addr(
const eeprom *dev,
uint32_t off,
uint8_t addr[EEPROM_MAX_ADDRESS_BYTES]
)
{
int shift = 24 - (4 - dev->address_bytes) * 8;
addr[0] = (uint8_t) (off >> shift);
shift -= 8;
addr[1] = (uint8_t) (off >> shift);
shift -= 8;
addr[2] = (uint8_t) (off >> shift);
shift -= 8;
addr[3] = (uint8_t) (off >> shift);
}
static ssize_t eeprom_read(
i2c_dev *base,
void *buf,
@@ -80,12 +97,7 @@ static ssize_t eeprom_read(
*/
uint16_t cur = (uint16_t) (todo < 255 ? todo : 255);
uint8_t addr[EEPROM_MAX_ADDRESS_BYTES] = {
(uint8_t) off,
(uint8_t) (off >> 8),
(uint8_t) (off >> 16),
(uint8_t) (off >> 24)
};
uint8_t addr[EEPROM_MAX_ADDRESS_BYTES];
i2c_msg msgs[2] = {
{
.addr = i2c_addr,
@@ -101,6 +113,7 @@ static ssize_t eeprom_read(
};
int err;
eeprom_set_addr(dev, off, addr);
err = i2c_bus_transfer(dev->base.bus, &msgs[0], RTEMS_ARRAY_SIZE(msgs));
if (err != 0) {
return err;
@@ -141,12 +154,7 @@ static ssize_t eeprom_write(
uint16_t i2c_addr = eeprom_i2c_addr(dev, off);
uint16_t rem = dev->page_size - (off & (dev->page_size - 1));
uint16_t cur = (uint16_t) (todo < rem ? todo : rem);
uint8_t addr[EEPROM_MAX_ADDRESS_BYTES] = {
(uint8_t) off,
(uint8_t) (off >> 8),
(uint8_t) (off >> 16),
(uint8_t) (off >> 24)
};
uint8_t addr[EEPROM_MAX_ADDRESS_BYTES];
i2c_msg msgs[2] = {
{
.addr = i2c_addr,
@@ -164,17 +172,24 @@ static ssize_t eeprom_write(
int err;
ssize_t m;
rtems_interval timeout;
bool before;
eeprom_set_addr(dev, off, addr);
err = i2c_bus_transfer(dev->base.bus, &msgs[0], RTEMS_ARRAY_SIZE(msgs));
if (err != 0) {
return err;
}
timeout = rtems_clock_tick_later(dev->program_timeout);
timeout = rtems_clock_tick_later(dev->program_timeout_in_ticks);
do {
before = rtems_clock_tick_before(timeout);
m = eeprom_read(&dev->base, &in[0], cur, off);
} while (m != cur && rtems_clock_tick_before(timeout));
if (m == cur) {
break;
}
} while (before);
if (m != cur) {
return -ETIMEDOUT;
@@ -217,6 +232,7 @@ int i2c_dev_register_eeprom(
)
{
uint32_t extra_address;
uint32_t ms_per_tick;
eeprom *dev;
if (address_bytes > EEPROM_MAX_ADDRESS_BYTES) {
@@ -252,7 +268,9 @@ int i2c_dev_register_eeprom(
dev->address_bytes = address_bytes;
dev->page_size = page_size_in_bytes;
dev->size = size_in_bytes;
dev->program_timeout = RTEMS_MILLISECONDS_TO_TICKS(program_timeout_in_ms);
ms_per_tick = rtems_configuration_get_milliseconds_per_tick();
dev->program_timeout_in_ticks = (program_timeout_in_ms + ms_per_tick - 1)
/ ms_per_tick + 1;
if (extra_address != 0) {
dev->i2c_address_mask = extra_address - 1;

View File

@@ -507,11 +507,14 @@ rtems_filesystem_global_location_t *rtems_filesystem_global_location_obtain(
* deferred. The next obtain call will do the actual release.
*
* @param[in] global_loc The global file system location. It must not be NULL.
* @param[in] deferred If true, then do a deferred release, otherwise release
* it immediately.
*
* @see rtems_filesystem_global_location_obtain().
*/
void rtems_filesystem_global_location_release(
rtems_filesystem_global_location_t *global_loc
rtems_filesystem_global_location_t *global_loc,
bool deferred
);
void rtems_filesystem_location_detach(

View File

@@ -39,7 +39,7 @@ int rtems_filesystem_chdir( rtems_filesystem_location_info_t *loc )
);
} else {
rtems_filesystem_location_error( &global_loc->location, ENOTDIR );
rtems_filesystem_global_location_release( global_loc );
rtems_filesystem_global_location_release( global_loc, true );
rv = -1;
}

View File

@@ -80,7 +80,7 @@ int chroot( const char *path )
}
if ( rv != 0 ) {
rtems_filesystem_global_location_release( new_root_loc );
rtems_filesystem_global_location_release( new_root_loc, true );
}
} else {
rv = -1;
@@ -89,7 +89,7 @@ int chroot( const char *path )
rtems_filesystem_eval_path_cleanup( &ctx );
if ( rv != 0 ) {
rtems_filesystem_global_location_release( new_current_loc );
rtems_filesystem_global_location_release( new_current_loc, false );
}
return rv;

View File

@@ -126,7 +126,7 @@ static int register_subordinate_file_system(
);
rtems_filesystem_mt_unlock();
} else {
rtems_filesystem_global_location_release( mt_point_node );
rtems_filesystem_global_location_release( mt_point_node, true );
}
} else {
rtems_filesystem_eval_path_error( &ctx, EBUSY );

View File

@@ -44,7 +44,10 @@ bool newlib_create_hook(
}
#endif
_REENT_INIT_PTR((creating_task->libc_reent)); /* GCC extension: structure constants */
extern void __sinit (struct _reent *s);
struct _reent *reent = (struct _reent *) creating_task->libc_reent;
_REENT_INIT_PTR((reent)); /* GCC extension: structure constants */
__sinit( reent );
return true;
}

View File

@@ -44,8 +44,8 @@ void rtems_libio_free_user_env(void *arg)
bool uses_global_env = env == &rtems_global_user_env;
if (!uses_global_env) {
rtems_filesystem_global_location_release(env->current_directory);
rtems_filesystem_global_location_release(env->root_directory);
rtems_filesystem_global_location_release(env->current_directory, false);
rtems_filesystem_global_location_release(env->root_directory, false);
free(env);
}
}

View File

@@ -301,8 +301,8 @@ void rtems_filesystem_eval_path_cleanup(
{
free_location(&ctx->currentloc);
rtems_filesystem_instance_unlock(&ctx->startloc->location);
rtems_filesystem_global_location_release(ctx->startloc);
rtems_filesystem_global_location_release(ctx->rootloc);
rtems_filesystem_global_location_release(ctx->startloc, false);
rtems_filesystem_global_location_release(ctx->rootloc, false);
}
void rtems_filesystem_eval_path_cleanup_with_parent(

View File

@@ -105,7 +105,7 @@ void rtems_filesystem_global_location_assign(
*lhs_global_loc_ptr = rhs_global_loc;
rtems_filesystem_mt_entry_unlock(lock_context);
rtems_filesystem_global_location_release(lhs_global_loc);
rtems_filesystem_global_location_release(lhs_global_loc, true);
}
static void release_with_count(
@@ -183,10 +183,11 @@ rtems_filesystem_global_location_t *rtems_filesystem_global_location_obtain(
}
void rtems_filesystem_global_location_release(
rtems_filesystem_global_location_t *global_loc
rtems_filesystem_global_location_t *global_loc,
bool deferred
)
{
if (_Thread_Dispatch_is_enabled()) {
if (!deferred) {
release_with_count(global_loc, 1);
} else {
rtems_interrupt_lock_context lock_context;
@@ -232,7 +233,7 @@ void rtems_filesystem_do_unmount(
rtems_filesystem_mt_lock();
rtems_chain_extract_unprotected(&mt_entry->mt_node);
rtems_filesystem_mt_unlock();
rtems_filesystem_global_location_release(mt_entry->mt_point_node);
rtems_filesystem_global_location_release(mt_entry->mt_point_node, false);
(*mt_entry->ops->fsunmount_me_h)(mt_entry);
if (mt_entry->unmount_task != 0) {

View File

@@ -1402,7 +1402,7 @@ siproc (unsigned char c, struct rtems_termios_tty *tty)
/*
* Fill the input buffer by polling the device
*/
static rtems_status_code
static void
fillBufferPoll (struct rtems_termios_tty *tty)
{
int n;
@@ -1449,23 +1449,27 @@ fillBufferPoll (struct rtems_termios_tty *tty)
}
}
}
return RTEMS_SUCCESSFUL;
}
/*
* Fill the input buffer from the raw input queue
*/
static rtems_status_code
static void
fillBufferQueue (struct rtems_termios_tty *tty)
{
rtems_termios_device_context *ctx = tty->device_context;
rtems_interval timeout = tty->rawInBufSemaphoreFirstTimeout;
rtems_status_code sc;
int wait = 1;
bool wait = true;
while ( wait ) {
rtems_interrupt_lock_context lock_context;
/*
* Process characters read from raw queue
*/
rtems_termios_device_lock_acquire (ctx, &lock_context);
while ((tty->rawInBuf.Head != tty->rawInBuf.Tail) &&
(tty->ccount < (CBUFSIZE-1))) {
unsigned char c;
@@ -1474,6 +1478,7 @@ fillBufferQueue (struct rtems_termios_tty *tty)
newHead = (tty->rawInBuf.Head + 1) % tty->rawInBuf.Size;
c = tty->rawInBuf.theBuf[newHead];
tty->rawInBuf.Head = newHead;
if(((tty->rawInBuf.Tail-newHead+tty->rawInBuf.Size)
% tty->rawInBuf.Size)
< tty->lowwater) {
@@ -1495,29 +1500,40 @@ fillBufferQueue (struct rtems_termios_tty *tty)
}
}
rtems_termios_device_lock_release (ctx, &lock_context);
/* continue processing new character */
if (tty->termios.c_lflag & ICANON) {
if (siproc (c, tty))
wait = 0;
wait = false;
} else {
siproc (c, tty);
if (tty->ccount >= tty->termios.c_cc[VMIN])
wait = 0;
wait = false;
}
timeout = tty->rawInBufSemaphoreTimeout;
rtems_termios_device_lock_acquire (ctx, &lock_context);
}
rtems_termios_device_lock_release (ctx, &lock_context);
/*
* Wait for characters
*/
if ( wait ) {
sc = rtems_semaphore_obtain(
tty->rawInBuf.Semaphore, tty->rawInBufSemaphoreOptions, timeout);
if (sc != RTEMS_SUCCESSFUL)
if (wait) {
if (tty->ccount < CBUFSIZE - 1) {
rtems_status_code sc;
sc = rtems_semaphore_obtain(
tty->rawInBuf.Semaphore, tty->rawInBufSemaphoreOptions, timeout);
if (sc != RTEMS_SUCCESSFUL)
break;
} else {
break;
}
}
}
return RTEMS_SUCCESSFUL;
}
rtems_status_code
@@ -1544,12 +1560,9 @@ rtems_termios_read (void *arg)
tty->cindex = tty->ccount = 0;
tty->read_start_column = tty->column;
if (tty->handler.poll_read != NULL && tty->handler.mode == TERMIOS_POLLED)
sc = fillBufferPoll (tty);
fillBufferPoll (tty);
else
sc = fillBufferQueue (tty);
if (sc != RTEMS_SUCCESSFUL)
tty->cindex = tty->ccount = 0;
fillBufferQueue (tty);
}
while (count && (tty->cindex < tty->ccount)) {
*buffer++ = tty->cbuf[tty->cindex++];
@@ -1584,7 +1597,6 @@ int
rtems_termios_enqueue_raw_characters (void *ttyp, const char *buf, int len)
{
struct rtems_termios_tty *tty = ttyp;
unsigned int newTail;
char c;
int dropped = 0;
bool flow_rcv = false; /* true, if flow control char received */
@@ -1649,12 +1661,19 @@ rtems_termios_enqueue_raw_characters (void *ttyp, const char *buf, int len)
rtems_termios_device_lock_release (ctx, &lock_context);
}
} else {
newTail = (tty->rawInBuf.Tail + 1) % tty->rawInBuf.Size;
/* if chars_in_buffer > highwater */
unsigned int head;
unsigned int oldTail;
unsigned int newTail;
rtems_termios_device_lock_acquire (ctx, &lock_context);
if ((((newTail - tty->rawInBuf.Head + tty->rawInBuf.Size)
% tty->rawInBuf.Size) > tty->highwater) &&
!(tty->flow_ctrl & FL_IREQXOF)) {
head = tty->rawInBuf.Head;
oldTail = tty->rawInBuf.Tail;
newTail = (oldTail + 1) % tty->rawInBuf.Size;
/* if chars_in_buffer > highwater */
if ((tty->flow_ctrl & FL_IREQXOF) != 0 && (((newTail - head
+ tty->rawInBuf.Size) % tty->rawInBuf.Size) > tty->highwater)) {
/* incoming data stream should be stopped */
tty->flow_ctrl |= FL_IREQXOF;
if ((tty->flow_ctrl & (FL_MDXOF | FL_ISNTXOF))
@@ -1676,15 +1695,12 @@ rtems_termios_enqueue_raw_characters (void *ttyp, const char *buf, int len)
}
}
/* reenable interrupts */
rtems_termios_device_lock_release (ctx, &lock_context);
if (newTail == tty->rawInBuf.Head) {
dropped++;
} else {
if (newTail != head) {
tty->rawInBuf.theBuf[newTail] = c;
tty->rawInBuf.Tail = newTail;
rtems_termios_device_lock_release (ctx, &lock_context);
/*
* check to see if rcv wakeup callback was set
*/
@@ -1692,6 +1708,9 @@ rtems_termios_enqueue_raw_characters (void *ttyp, const char *buf, int len)
(*tty->tty_rcv.sw_pfn)(&tty->termios, tty->tty_rcv.sw_arg);
tty->tty_rcvwakeup = 1;
}
} else {
++dropped;
rtems_termios_device_lock_release (ctx, &lock_context);
}
}
}

View File

@@ -25,6 +25,7 @@ libdl_a_SOURCES = \
rtl-string.c \
rtl-sym.c \
rtl-trace.c \
rtl-unwind-dw2.c \
rtl-unresolved.c
libdl_a_SOURCES += rtl-mdreloc-@RTEMS_CPU@.c

View File

@@ -38,7 +38,8 @@ convert_ascii_to_voidp (const char* arg)
int
shell_dlopen (int argc, char* argv[])
{
int arg;
int arg;
char *err;
for (arg = 1; arg < argc; arg++)
{
void* handle = dlopen (argv[arg], RTLD_NOW | RTLD_GLOBAL);
@@ -53,7 +54,10 @@ shell_dlopen (int argc, char* argv[])
printf ("handle: %p %s\n", handle, message);
}
else
printf ("error: %s\n", dlerror ());
{
err = dlerror ();
printf ("error: %s\n", err ? err : "");
}
}
return 0;
}

View File

@@ -18,6 +18,7 @@
#include <stdint.h>
#include <dlfcn.h>
#include <rtems/rtl/rtl.h>
#include "rtl-error.h"
static rtems_rtl_obj_t*
dl_get_obj_from_handle (void* handle)
@@ -125,12 +126,15 @@ dlsym (void* handle, const char *symbol)
return symval;
}
const char*
char*
dlerror (void)
{
static char msg[64];
rtems_rtl_get_error (msg, sizeof (msg));
return msg;
rtems_rtl_clear_error ();
if (msg[0] == '\0')
return NULL;
return msg;
}
int

View File

@@ -56,7 +56,7 @@ int dladdr(void * __restrict, Dl_info * __restrict);
int dlctl(void *, int, void *);
#endif
int dlinfo(void *, int, void *);
const char *dlerror(void);
char *dlerror(void);
__END_DECLS
/* Values for dlopen `mode'. */

View File

@@ -80,7 +80,8 @@
#define R_ARM_ALU_SBREL_19_12 36
#define R_ARM_ALU_SBREL_27_20 37
#define R_ARM_V4BX 40
#define R_ARM_PREL31 41
#define R_ARM_TARGET2 41
#define R_ARM_PREL31 42
#define R_ARM_MOVW_ABS_NC 43
#define R_ARM_MOVT_ABS 44

View File

@@ -459,6 +459,10 @@ typedef struct {
#define SHF_WRITE 0x1 /* Section contains writable data */
#define SHF_ALLOC 0x2 /* Section occupies memory */
#define SHF_EXECINSTR 0x4 /* Section contains executable insns */
#define SHF_MERGE 0x10 /* Section contains data that can be merged */
#define SHF_STRINGS 0x20 /* Section contains null-terminated strings */
#define SHF_INFO_LINK 0x40 /* Section header's sh_info holds table index */
#define SHF_LINK_ORDER 0x80 /* Section has special ordering requirements */
#define SHF_MASKOS 0x0f000000 /* Operating system specific values */
#define SHF_MASKPROC 0xf0000000 /* Processor-specific values */
@@ -949,13 +953,13 @@ typedef struct {
#define SYMINFO_NUM 2
/*
* These constants are used for Elf32_Verdef struct's version number.
* These constants are used for Elf32_Verdef struct's version number.
*/
#define VER_DEF_NONE 0
#define VER_DEF_CURRENT 1
/*
* These constants are used for Elf32_Verdef struct's vd_flags.
* These constants are used for Elf32_Verdef struct's vd_flags.
*/
#define VER_FLG_BASE 0x1
#define VER_FLG_WEAK 0x2
@@ -967,7 +971,7 @@ typedef struct {
#define VER_NDX_GLOBAL 1
/*
* These constants are used for Elf32_Verneed struct's version number.
* These constants are used for Elf32_Verneed struct's version number.
*/
#define VER_NEED_NONE 0
#define VER_NEED_CURRENT 1

View File

@@ -19,6 +19,7 @@
#include "config.h"
#endif
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

View File

@@ -152,6 +152,7 @@ rtems_rtl_alloc_indirect_del (rtems_rtl_alloc_tag_t tag,
bool
rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
void** const_base, size_t const_size,
void** eh_base, size_t eh_size,
void** data_base, size_t data_size,
void** bss_base, size_t bss_size)
{
@@ -173,7 +174,20 @@ rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
const_size, false);
if (!*const_base)
{
rtems_rtl_alloc_module_del (text_base, const_base, data_base, bss_base);
rtems_rtl_alloc_module_del (text_base, const_base, eh_base,
data_base, bss_base);
return false;
}
}
if (eh_size)
{
*eh_base = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_READ,
eh_size, false);
if (!*eh_base)
{
rtems_rtl_alloc_module_del (text_base, const_base, eh_base,
data_base, bss_base);
return false;
}
}
@@ -184,7 +198,8 @@ rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
data_size, false);
if (!*data_base)
{
rtems_rtl_alloc_module_del (text_base, const_base, data_base, bss_base);
rtems_rtl_alloc_module_del (text_base, const_base, eh_base,
data_base, bss_base);
return false;
}
}
@@ -195,7 +210,8 @@ rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
bss_size, false);
if (!*bss_base)
{
rtems_rtl_alloc_module_del (text_base, const_base, data_base, bss_base);
rtems_rtl_alloc_module_del (text_base, const_base, eh_base,
data_base, bss_base);
return false;
}
}
@@ -206,12 +222,14 @@ rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
void
rtems_rtl_alloc_module_del (void** text_base,
void** const_base,
void** eh_base,
void** data_base,
void** bss_base)
{
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ_WRITE, *bss_base);
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ_WRITE, *data_base);
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ, *eh_base);
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ, *const_base);
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ_EXEC, *text_base);
*text_base = *const_base = *data_base = *bss_base = NULL;
*text_base = *const_base = *eh_base = *data_base = *bss_base = NULL;
}

View File

@@ -146,6 +146,8 @@ void rtems_rtl_alloc_indirect_del (rtems_rtl_alloc_tag_t tag,
* @param text_size The size of the read/exec section.
* @param const_base Pointer to the const base pointer.
* @param const_size The size of the read only section.
* @param eh_base Pointer to the eh base pointer.
* @param eh_size The size of the eh section.
* @param data_base Pointer to the data base pointer.
* @param data_size The size of the read/write secton.
* @param bss_base Pointer to the bss base pointer.
@@ -155,6 +157,7 @@ void rtems_rtl_alloc_indirect_del (rtems_rtl_alloc_tag_t tag,
*/
bool rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
void** const_base, size_t const_size,
void** eh_base, size_t eh_size,
void** data_base, size_t data_size,
void** bss_base, size_t bss_size);
@@ -163,11 +166,13 @@ bool rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
*
* @param text_base Pointer to the text base pointer.
* @param const_base Pointer to the const base pointer.
* @param eh_base Pointer to the eh base pointer.
* @param data_base Pointer to the data base pointer.
* @param bss_base Pointer to the bss base pointer.
*/
void rtems_rtl_alloc_module_del (void** text_base, void** const_base,
void** data_base, void** bss_base);
void** eh_base, void** data_base,
void** bss_base);
#ifdef __cplusplus
}

View File

@@ -45,10 +45,10 @@ _rtld_debug_state (void)
int
_rtld_linkmap_add (rtems_rtl_obj_t* obj)
{
struct link_map* l = (struct link_map*)obj->detail;
struct link_map* l = obj->linkmap;
struct link_map* prev;
uint32_t obj_num = obj->obj_num;
int i;
uint32_t obj_num = obj->obj_num;
int i;
if (rtems_rtl_trace (RTEMS_RTL_TRACE_DETAIL))
printf ("rtl: linkmap_add\n");
@@ -78,8 +78,10 @@ _rtld_linkmap_add (rtems_rtl_obj_t* obj)
void
_rtld_linkmap_delete (rtems_rtl_obj_t* obj)
{
struct link_map* l = (struct link_map*)obj->detail;
/* link_maps are allocated together if not 1 */
struct link_map* l = obj->linkmap;
/*
* link_maps are allocated together if not 1
*/
struct link_map* e = l + obj->obj_num - 1;
while (e && e->l_next) e = e->l_next;
@@ -90,7 +92,7 @@ _rtld_linkmap_delete (rtems_rtl_obj_t* obj)
e->l_next->l_prev = NULL;
return;
}
if ((l->l_prev->l_next = e->l_next) != NULL)
e->l_next->l_prev = l->l_prev;
return;
}

View File

@@ -30,6 +30,7 @@
#include "rtl-elf.h"
#include "rtl-error.h"
#include "rtl-trace.h"
#include "rtl-unwind.h"
#include "rtl-unresolved.h"
/**
@@ -169,6 +170,9 @@ rtems_rtl_elf_relocator (rtems_rtl_obj_t* obj,
&relbuf[0], reloc_size))
return false;
/*
* Read the symbol details.
*/
if (is_rela)
off = (obj->ooffset + symsect->offset +
(ELF_R_SYM (rela->r_info) * sizeof (sym)));
@@ -246,7 +250,7 @@ rtems_rtl_elf_relocator (rtems_rtl_obj_t* obj,
if (is_rela)
{
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
printf ("rtl: rela: sym:%s(%-2d)=%08lx type:%-2d off:%08lx addend:%d\n",
printf ("rtl: rela: sym:%s(%d)=%08lx type:%d off:%08lx addend:%d\n",
symname, (int) ELF_R_SYM (rela->r_info), symvalue,
(int) ELF_R_TYPE (rela->r_info), rela->r_offset, (int) rela->r_addend);
if (!rtems_rtl_elf_relocate_rela (obj, rela, targetsect,
@@ -256,7 +260,7 @@ rtems_rtl_elf_relocator (rtems_rtl_obj_t* obj,
else
{
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
printf ("rtl: rel: sym:%s(%-2d)=%08lx type:%-2d off:%08lx\n",
printf ("rtl: rel: sym:%s(%d)=%08lx type:%d off:%08lx\n",
symname, (int) ELF_R_SYM (rel->r_info), symvalue,
(int) ELF_R_TYPE (rel->r_info), rel->r_offset);
if (!rtems_rtl_elf_relocate_rel (obj, rel, targetsect,
@@ -300,7 +304,7 @@ rtems_rtl_obj_relocate_unresolved (rtems_rtl_unresolv_reloc_t* reloc,
rela.r_info = reloc->rel[REL_R_INFO];
rela.r_addend = reloc->rel[REL_R_ADDEND];
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
printf ("rtl: rela: sym:%-2d type:%-2d off:%08lx addend:%d\n",
printf ("rtl: rela: sym:%d type:%d off:%08lx addend:%d\n",
(int) ELF_R_SYM (rela.r_info), (int) ELF_R_TYPE (rela.r_info),
rela.r_offset, (int) rela.r_addend);
if (!rtems_rtl_elf_relocate_rela (reloc->obj, &rela, sect,
@@ -313,7 +317,7 @@ rtems_rtl_obj_relocate_unresolved (rtems_rtl_unresolv_reloc_t* reloc,
rel.r_offset = reloc->rel[REL_R_OFFSET];
rel.r_info = reloc->rel[REL_R_INFO];
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
printf ("rtl: rel: sym:%-2d type:%-2d off:%08lx\n",
printf ("rtl: rel: sym:%d type:%d off:%08lx\n",
(int) ELF_R_SYM (rel.r_info), (int) ELF_R_TYPE (rel.r_info),
rel.r_offset);
if (!rtems_rtl_elf_relocate_rel (reloc->obj, &rel, sect,
@@ -652,6 +656,11 @@ rtems_rtl_elf_parse_sections (rtems_rtl_obj_t* obj, int fd, Elf_Ehdr* ehdr)
flags = 0;
if (rtems_rtl_trace (RTEMS_RTL_TRACE_DETAIL))
printf ("rtl: section: %2d: type=%d flags=%08x link=%d info=%d\n",
section, (int) shdr.sh_type, (unsigned int) shdr.sh_flags,
(int) shdr.sh_link, (int) shdr.sh_info);
switch (shdr.sh_type)
{
case SHT_NULL:
@@ -707,9 +716,16 @@ rtems_rtl_elf_parse_sections (rtems_rtl_obj_t* obj, int fd, Elf_Ehdr* ehdr)
break;
default:
if (rtems_rtl_trace (RTEMS_RTL_TRACE_WARNING))
printf ("rtl: unsupported section: %2d: type=%02d flags=%02x\n",
section, (int) shdr.sh_type, (int) shdr.sh_flags);
/*
* See if there are architecture specific flags?
*/
flags = rtems_rtl_elf_section_flags (obj, &shdr);
if (flags == 0)
{
if (rtems_rtl_trace (RTEMS_RTL_TRACE_WARNING))
printf ("rtl: unsupported section: %2d: type=%02d flags=%02x\n",
section, (int) shdr.sh_type, (int) shdr.sh_flags);
}
break;
}
@@ -718,6 +734,13 @@ rtems_rtl_elf_parse_sections (rtems_rtl_obj_t* obj, int fd, Elf_Ehdr* ehdr)
char* name;
size_t len;
/*
* If link ordering this section must appear in the same order in memory
* as the linked-to section relative to the sections it loads with.
*/
if ((shdr.sh_flags & SHF_LINK_ORDER) != 0)
flags |= RTEMS_RTL_OBJ_SECT_LINK;
len = RTEMS_RTL_ELF_STRING_MAX;
if (!rtems_rtl_obj_cache_read (strings, fd,
sectstroff + shdr.sh_name,
@@ -729,6 +752,12 @@ rtems_rtl_elf_parse_sections (rtems_rtl_obj_t* obj, int fd, Elf_Ehdr* ehdr)
if (strcmp (".dtors", name) == 0)
flags |= RTEMS_RTL_OBJ_SECT_DTOR;
if (rtems_rtl_elf_unwind_parse (obj, name, flags))
{
flags &= ~(RTEMS_RTL_OBJ_SECT_TEXT | RTEMS_RTL_OBJ_SECT_CONST);
flags |= RTEMS_RTL_OBJ_SECT_EH;
}
if (!rtems_rtl_obj_add_section (obj, section, name,
shdr.sh_size, shdr.sh_offset,
shdr.sh_addralign, shdr.sh_link,
@@ -771,16 +800,19 @@ rtems_rtl_elf_file_check (rtems_rtl_obj_t* obj, int fd)
return true;
}
bool rtems_rtl_elf_load_details (rtems_rtl_obj_t* obj)
static bool
rtems_rtl_elf_load_linkmap (rtems_rtl_obj_t* obj)
{
rtems_chain_control* sections = NULL;
rtems_chain_node* node = NULL;
size_t mask = 0;
struct link_map* l = NULL;
int sec_num = 0;
section_detail* sd;
int i = 0;
/* caculate the size of sections' name. */
/*
* Caculate the size of sections' name.
*/
for (mask = RTEMS_RTL_OBJ_SECT_TEXT;
mask <= RTEMS_RTL_OBJ_SECT_BSS;
@@ -791,7 +823,6 @@ bool rtems_rtl_elf_load_details (rtems_rtl_obj_t* obj)
while (!rtems_chain_is_tail (sections, node))
{
rtems_rtl_obj_sect_t* sect = (rtems_rtl_obj_sect_t*) node;
if ((sect->size != 0) && ((sect->flags & mask) != 0))
{
++sec_num;
@@ -801,32 +832,31 @@ bool rtems_rtl_elf_load_details (rtems_rtl_obj_t* obj)
}
obj->obj_num = 1;
obj->detail = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
sizeof(struct link_map) +
sec_num * sizeof (section_detail), true);
if (!obj->detail)
obj->linkmap = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
sizeof(struct link_map) +
sec_num * sizeof (section_detail), true);
if (!obj->linkmap)
{
rtems_rtl_set_error (ENOMEM, "no memory for obj global syms");
rtems_rtl_set_error (ENOMEM, "no memory for obj linkmap");
return false;
}
l = (struct link_map*) obj->detail;
l->name = obj->oname;
l->sec_num = sec_num;
l->sec_detail = (section_detail*) (l + 1);
l->rpathlen = 0;
l->rpath = NULL;
l->l_next = NULL;
l->l_prev = NULL;
l->sec_addr[rap_text] = obj->text_base;
l->sec_addr[rap_const] = obj->const_base;
l->sec_addr[rap_data] = obj->data_base;
l->sec_addr[rap_bss] = obj->bss_base;
obj->linkmap->name = obj->oname;
obj->linkmap->sec_num = sec_num;
obj->linkmap->sec_detail = (section_detail*) (obj->linkmap + 1);
obj->linkmap->rpathlen = 0;
obj->linkmap->rpath = NULL;
obj->linkmap->l_next = NULL;
obj->linkmap->l_prev = NULL;
obj->linkmap->sec_addr[rap_text] = obj->text_base;
obj->linkmap->sec_addr[rap_const] = obj->const_base;
obj->linkmap->sec_addr[rap_data] = obj->data_base;
obj->linkmap->sec_addr[rap_bss] = obj->bss_base;
section_detail* sd = l->sec_detail;
sd = obj->linkmap->sec_detail;
sections = &obj->sections;
node = rtems_chain_first (sections);
for (mask = RTEMS_RTL_OBJ_SECT_TEXT;
mask <= RTEMS_RTL_OBJ_SECT_BSS;
mask <<= 1)
@@ -948,11 +978,23 @@ rtems_rtl_elf_file_load (rtems_rtl_obj_t* obj, int fd)
rtems_rtl_symbol_obj_erase_local (obj);
if (!rtems_rtl_elf_load_details (obj))
if (!rtems_rtl_elf_load_linkmap (obj))
{
return false;
}
if (!rtems_rtl_elf_unwind_register (obj))
{
return false;
}
return true;
}
bool
rtems_rtl_elf_file_unload (rtems_rtl_obj_t* obj)
{
rtems_rtl_elf_unwind_deregister (obj);
return true;
}

View File

@@ -54,6 +54,18 @@ extern "C" {
*/
#define RTEMS_RTL_ELF_STRING_MAX (256)
/**
* Architecture specific handler to translate unknown section flags to RTL
* section flags.
*
* @param obj The object file being relocated.
* @param shdr The ELF section header.
* @retval 0 Unknown or unsupported flags.
* @retval uint32_t RTL object file flags.
*/
uint32_t rtems_rtl_elf_section_flags (const rtems_rtl_obj_t* obj,
const Elf_Shdr* shdr);
/**
* Architecture specific handler to check is a relocation record's type is
* required to resolve a symbol.
@@ -136,13 +148,6 @@ bool rtems_rtl_elf_find_symbol (rtems_rtl_obj_t* obj,
*/
bool rtems_rtl_elf_file_check (rtems_rtl_obj_t* obj, int fd);
/**
* The ELF file details handler.
*
* @param obj Load the details of the obj.
*/
bool rtems_rtl_elf_load_details (rtems_rtl_obj_t* obj);
/**
* The ELF format load handler.
*
@@ -151,6 +156,13 @@ bool rtems_rtl_elf_load_details (rtems_rtl_obj_t* obj);
*/
bool rtems_rtl_elf_file_load (rtems_rtl_obj_t* obj, int fd);
/**
* The ELF format unload handler.
*
* @param obj The object to unload.
*/
bool rtems_rtl_elf_file_unload (rtems_rtl_obj_t* obj);
/**
* The ELF format signature handler.
*

View File

@@ -17,6 +17,7 @@
#include "config.h"
#endif
#include <errno.h>
#include <stdio.h>
#include <stdarg.h>
@@ -39,9 +40,27 @@ int
rtems_rtl_get_error (char* message, size_t max_message)
{
rtems_rtl_data_t* rtl = rtems_rtl_lock ();
int last_errno = rtl->last_errno;
strncpy (message, rtl->last_error, sizeof (rtl->last_error));
rtems_rtl_unlock ();
return last_errno;
if (rtl != NULL)
{
int last_errno = rtl->last_errno;
strncpy (message, rtl->last_error, sizeof (rtl->last_error));
rtems_rtl_unlock ();
return last_errno;
}
strncpy(message, "RTL init error", max_message);
return EIO;
}
void
rtems_rtl_clear_error (void)
{
rtems_rtl_data_t* rtl = rtems_rtl_lock ();
if (rtl != NULL)
{
rtl->last_errno = 0;
rtl->last_error[0] = '\0';
rtems_rtl_unlock ();
}
}

View File

@@ -37,6 +37,11 @@ extern "C" {
*/
void rtems_rtl_set_error (int error, const char* format, ...) RTEMS_RTL_PRINTF_ATTR;
/**
* Clears the error.
*/
void rtems_rtl_clear_error (void);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@@ -10,11 +10,14 @@
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unwind.h>
#include <unwind-arm-common.h>
#include <rtems/rtl/rtl.h>
#include "rtl-elf.h"
#include "rtl-error.h"
#include "rtl-trace.h"
#include "rtl-unwind.h"
/*
* It is possible for the compiler to emit relocations for unaligned data.
@@ -23,6 +26,8 @@
#define RELOC_ALIGNED_P(x) \
(((uintptr_t)(x) & (sizeof(void *) - 1)) == 0)
#define SHT_ARM_EXIDX 0x70000001 /* Section holds ARM unwind info. */
static inline Elf_Addr
load_ptr(void *where)
{
@@ -52,6 +57,24 @@ isThumb(Elf_Word symvalue)
else return false;
}
static inline Elf_SOff
sign_extend31(Elf_Addr val)
{
if (0x40000000 & val)
val = ~((Elf_Addr)0x7fffffff) | (0x7fffffff & val);
return 0x7fffffff & val;
}
uint32_t
rtems_rtl_elf_section_flags (const rtems_rtl_obj_t* obj,
const Elf_Shdr* shdr)
{
uint32_t flags = 0;
if (shdr->sh_type == SHT_ARM_EXIDX)
flags = RTEMS_RTL_OBJ_SECT_EH | RTEMS_RTL_OBJ_SECT_LOAD;
return flags;
}
bool
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
{
@@ -87,8 +110,11 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
where = (Elf_Addr *)(sect->base + rel->r_offset);
switch (ELF_R_TYPE(rel->r_info)) {
case R_TYPE(NONE):
break;
case R_TYPE(NONE):
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
printf ("rtl: NONE %p in %s\n", where, rtems_rtl_obj_oname (obj));
}
break;
case R_TYPE(CALL): /* BL/BLX */
case R_TYPE(JUMP24): /* B/BL<cond> */
@@ -165,24 +191,32 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
case R_TYPE(REL32): /* word32 (S + A) | T - P */
case R_TYPE(ABS32): /* word32 (S + A) | T */
case R_TYPE(GLOB_DAT): /* word32 (S + A) | T */
case R_TYPE(PREL31): /* word32 (S + A) | T - P */
case R_TYPE(TARGET2): /* Equivalent to REL32 */
if (__predict_true(RELOC_ALIGNED_P(where))) {
tmp = *where + symvalue;
if (isThumb(symvalue))
tmp |= 1;
if (ELF_R_TYPE(rel->r_info) == R_TYPE(REL32))
if (ELF_R_TYPE(rel->r_info) == R_TYPE(REL32) ||
ELF_R_TYPE(rel->r_info) == R_TYPE(TARGET2))
tmp -= (Elf_Addr)where;
else if (ELF_R_TYPE(rel->r_info) == R_TYPE(PREL31))
tmp = sign_extend31(tmp - (Elf_Addr)where);
*where = tmp;
} else {
tmp = load_ptr(where) + symvalue;
if (isThumb(symvalue))
tmp |= 1;
if (ELF_R_TYPE(rel->r_info) == R_TYPE(REL32))
if (ELF_R_TYPE(rel->r_info) == R_TYPE(REL32) ||
ELF_R_TYPE(rel->r_info) == R_TYPE(TARGET2))
tmp -= (Elf_Addr)where;
else if (ELF_R_TYPE(rel->r_info) == R_TYPE(PREL31))
tmp = sign_extend31(tmp - (Elf_Addr)where);
store_ptr(where, tmp);
}
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
printf ("rtl: REL32/ABS32/GLOB_DAT %p @ %p in %s",
printf ("rtl: REL32/ABS32/GLOB_DAT/PREL31/TARGET2 %p @ %p in %s\n",
(void *)tmp, where, rtems_rtl_obj_oname (obj));
break;
@@ -306,7 +340,7 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
(void *)*where, where, rtems_rtl_obj_oname (obj));
break;
default:
default:
printf ("rtl: reloc unknown: sym = %lu, type = %lu, offset = %p, "
"contents = %p\n",
ELF_R_SYM(rel->r_info), (uint32_t) ELF_R_TYPE(rel->r_info),
@@ -315,9 +349,83 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
"%s: Unsupported relocation type %ld "
"in non-PLT relocations",
sect->name, (uint32_t) ELF_R_TYPE(rel->r_info));
return false;
return false;
}
return true;
return true;
}
bool
rtems_rtl_elf_unwind_parse (const rtems_rtl_obj_t* obj,
const char* name,
uint32_t flags)
{
/*
* We location the EH sections in section flags.
*/
return false;
}
bool
rtems_rtl_elf_unwind_register (rtems_rtl_obj_t* obj)
{
return true;
}
bool
rtems_rtl_elf_unwind_deregister (rtems_rtl_obj_t* obj)
{
obj->loader = NULL;
return true;
}
/* An exception index table entry. */
typedef struct __EIT_entry
{
_uw fnoffset;
_uw content;
} __EIT_entry;
/* The exception index table location in the base module */
extern __EIT_entry __exidx_start;
extern __EIT_entry __exidx_end;
/*
* A weak reference is in libgcc, provide a real version and provide a way to
* manage loaded modules.
*
* Passed in the return address and a reference to the number of records
* found. We set the start of the exidx data and the number of records.
*/
_Unwind_Ptr __gnu_Unwind_Find_exidx (_Unwind_Ptr return_address,
int* nrec) __attribute__ ((__noinline__,
__used__,
__noclone__));
_Unwind_Ptr __gnu_Unwind_Find_exidx (_Unwind_Ptr return_address,
int* nrec)
{
rtems_rtl_data_t* rtl;
rtems_chain_node* node;
__EIT_entry* exidx_start = &__exidx_start;
__EIT_entry* exidx_end = &__exidx_end;
rtl = rtems_rtl_lock ();
node = rtems_chain_first (&rtl->objects);
while (!rtems_chain_is_tail (&rtl->objects, node)) {
rtems_rtl_obj_t* obj = (rtems_rtl_obj_t*) node;
if (rtems_rtl_obj_text_inside (obj, (void*) return_address)) {
exidx_start = (__EIT_entry*) obj->eh_base;
exidx_end = (__EIT_entry*) (obj->eh_base + obj->eh_size);
break;
}
node = rtems_chain_next (node);
}
rtems_rtl_unlock ();
*nrec = exidx_end - exidx_start;
return (_Unwind_Ptr) exidx_start;
}

View File

@@ -6,6 +6,15 @@
#include "rtl-elf.h"
#include "rtl-error.h"
#include "rtl-trace.h"
#include "rtl-unwind.h"
#include "rtl-unwind-dw2.h"
uint32_t
rtems_rtl_elf_section_flags (const rtems_rtl_obj_t* obj,
const Elf_Shdr* shdr)
{
return 0;
}
bool
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
@@ -113,3 +122,23 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
rtems_rtl_set_error (EINVAL, "rel type record not supported");
return false;
}
bool
rtems_rtl_elf_unwind_parse (const rtems_rtl_obj_t* obj,
const char* name,
uint32_t flags)
{
return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
}
bool
rtems_rtl_elf_unwind_register (rtems_rtl_obj_t* obj)
{
return rtems_rtl_elf_unwind_dw2_register (obj);
}
bool
rtems_rtl_elf_unwind_deregister (rtems_rtl_obj_t* obj)
{
return rtems_rtl_elf_unwind_dw2_deregister (obj);
}

View File

@@ -9,6 +9,15 @@
#include "rtl-elf.h"
#include "rtl-error.h"
#include "rtl-trace.h"
#include "rtl-unwind.h"
#include "rtl-unwind-dw2.h"
uint32_t
rtems_rtl_elf_section_flags (const rtems_rtl_obj_t* obj,
const Elf_Shdr* shdr)
{
return 0;
}
bool
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
@@ -99,3 +108,23 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
rtems_rtl_set_error (EINVAL, "rel type record not supported");
return false;
}
bool
rtems_rtl_elf_unwind_parse (const rtems_rtl_obj_t* obj,
const char* name,
uint32_t flags)
{
return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
}
bool
rtems_rtl_elf_unwind_register (rtems_rtl_obj_t* obj)
{
return rtems_rtl_elf_unwind_dw2_register (obj);
}
bool
rtems_rtl_elf_unwind_deregister (rtems_rtl_obj_t* obj)
{
return rtems_rtl_elf_unwind_dw2_deregister (obj);
}

View File

@@ -15,6 +15,15 @@
#include "rtl-elf.h"
#include "rtl-error.h"
#include "rtl-trace.h"
#include "rtl-unwind.h"
#include "rtl-unwind-dw2.h"
uint32_t
rtems_rtl_elf_section_flags (const rtems_rtl_obj_t* obj,
const Elf_Shdr* shdr)
{
return 0;
}
bool
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
@@ -101,3 +110,23 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
return true;
}
bool
rtems_rtl_elf_unwind_parse (const rtems_rtl_obj_t* obj,
const char* name,
uint32_t flags)
{
return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
}
bool
rtems_rtl_elf_unwind_register (rtems_rtl_obj_t* obj)
{
return rtems_rtl_elf_unwind_dw2_register (obj);
}
bool
rtems_rtl_elf_unwind_deregister (rtems_rtl_obj_t* obj)
{
return rtems_rtl_elf_unwind_dw2_deregister (obj);
}

View File

@@ -9,6 +9,15 @@
#include "rtl-elf.h"
#include "rtl-error.h"
#include "rtl-trace.h"
#include "rtl-unwind.h"
#include "rtl-unwind-dw2.h"
uint32_t
rtems_rtl_elf_section_flags (const rtems_rtl_obj_t* obj,
const Elf_Shdr* shdr)
{
return 0;
}
bool
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
@@ -118,3 +127,23 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
rtems_rtl_set_error (EINVAL, "rela type record not supported");
return false;
}
bool
rtems_rtl_elf_unwind_parse (const rtems_rtl_obj_t* obj,
const char* name,
uint32_t flags)
{
return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
}
bool
rtems_rtl_elf_unwind_register (rtems_rtl_obj_t* obj)
{
return rtems_rtl_elf_unwind_dw2_register (obj);
}
bool
rtems_rtl_elf_unwind_deregister (rtems_rtl_obj_t* obj)
{
return rtems_rtl_elf_unwind_dw2_deregister (obj);
}

View File

@@ -15,6 +15,8 @@
#include "rtl-elf.h"
#include "rtl-error.h"
#include "rtl-trace.h"
#include "rtl-unwind.h"
#include "rtl-unwind-dw2.h"
static inline int overflow_8_check(int value)
{
@@ -30,6 +32,13 @@ static inline int overflow_16_check(int value)
return false;
}
uint32_t
rtems_rtl_elf_section_flags (const rtems_rtl_obj_t* obj,
const Elf_Shdr* shdr)
{
return 0;
}
bool
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
{
@@ -146,3 +155,23 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
rtems_rtl_set_error (EINVAL, "rel type record not supported");
return false;
}
bool
rtems_rtl_elf_unwind_parse (const rtems_rtl_obj_t* obj,
const char* name,
uint32_t flags)
{
return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
}
bool
rtems_rtl_elf_unwind_register (rtems_rtl_obj_t* obj)
{
return rtems_rtl_elf_unwind_dw2_register (obj);
}
bool
rtems_rtl_elf_unwind_deregister (rtems_rtl_obj_t* obj)
{
return rtems_rtl_elf_unwind_dw2_deregister (obj);
}

View File

@@ -9,6 +9,15 @@
#include "rtl-elf.h"
#include "rtl-error.h"
#include "rtl-trace.h"
#include "rtl-unwind.h"
#include "rtl-unwind-dw2.h"
uint32_t
rtems_rtl_elf_section_flags (const rtems_rtl_obj_t* obj,
const Elf_Shdr* shdr)
{
return 0;
}
bool
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
@@ -188,3 +197,23 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
return true;
}
bool
rtems_rtl_elf_unwind_parse (const rtems_rtl_obj_t* obj,
const char* name,
uint32_t flags)
{
return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
}
bool
rtems_rtl_elf_unwind_register (rtems_rtl_obj_t* obj)
{
return rtems_rtl_elf_unwind_dw2_register (obj);
}
bool
rtems_rtl_elf_unwind_deregister (rtems_rtl_obj_t* obj)
{
return rtems_rtl_elf_unwind_dw2_deregister (obj);
}

View File

@@ -10,6 +10,15 @@
#include "rtl-elf.h"
#include "rtl-error.h"
#include "rtl-trace.h"
#include "rtl-unwind.h"
#include "rtl-unwind-dw2.h"
uint32_t
rtems_rtl_elf_section_flags (const rtems_rtl_obj_t* obj,
const Elf_Shdr* shdr)
{
return 0;
}
bool
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
@@ -86,3 +95,23 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
rtems_rtl_set_error (EINVAL, "rel type record not supported");
return false;
}
bool
rtems_rtl_elf_unwind_parse (const rtems_rtl_obj_t* obj,
const char* name,
uint32_t flags)
{
return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
}
bool
rtems_rtl_elf_unwind_register (rtems_rtl_obj_t* obj)
{
return rtems_rtl_elf_unwind_dw2_register (obj);
}
bool
rtems_rtl_elf_unwind_deregister (rtems_rtl_obj_t* obj)
{
return rtems_rtl_elf_unwind_dw2_deregister (obj);
}

View File

@@ -15,11 +15,19 @@
#include "rtl-elf.h"
#include "rtl-error.h"
#include "rtl-trace.h"
#include "rtl-unwind.h"
#include "rtl-unwind-dw2.h"
#define ha(x) ((((u_int32_t)(x) & 0x8000) ? \
((u_int32_t)(x) + 0x10000) : (u_int32_t)(x)) >> 16)
#define l(x) ((u_int32_t)(x) & 0xffff)
uint32_t
rtems_rtl_elf_section_flags (const rtems_rtl_obj_t* obj,
const Elf_Shdr* shdr)
{
return 0;
}
bool
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
@@ -158,6 +166,22 @@ rtems_rtl_elf_relocate_rela (const rtems_rtl_obj_t* obj,
(void *)*where, where, rtems_rtl_obj_oname (obj));
break;
case R_TYPE(SDAREL16):
/*
* A sign-extended 16 bit value relative to _SDA_BASE_, for use with
* small data items.
*/
mask = 0xffff;
tmp = *((Elf32_Half*) where);
tmp &= ~mask;
tmp |= (symvalue + rela->r_addend - (Elf_Addr)where) & mask;
*((Elf32_Half*) where) = tmp;
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
printf ("rtl: SDAREL16 %p @ %p in %s\n",
(void *) (uintptr_t) *((Elf32_Half*) where),
where, rtems_rtl_obj_oname (obj));
break;
default:
printf ("rtl: reloc unknown: sym = %lu, type = %lu, offset = %p, "
"contents = %p\n",
@@ -183,3 +207,23 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
printf ("rtl: rel type record not supported; please report\n");
return false;
}
bool
rtems_rtl_elf_unwind_parse (const rtems_rtl_obj_t* obj,
const char* name,
uint32_t flags)
{
return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
}
bool
rtems_rtl_elf_unwind_register (rtems_rtl_obj_t* obj)
{
return rtems_rtl_elf_unwind_dw2_register (obj);
}
bool
rtems_rtl_elf_unwind_deregister (rtems_rtl_obj_t* obj)
{
return rtems_rtl_elf_unwind_dw2_deregister (obj);
}

View File

@@ -41,6 +41,8 @@
#include "rtl-elf.h"
#include "rtl-error.h"
#include "rtl-trace.h"
#include "rtl-unwind.h"
#include "rtl-unwind-dw2.h"
/*
* The following table holds for each relocation type:
@@ -128,6 +130,13 @@ static const int reloc_target_bitmask[] = {
};
#define RELOC_VALUE_BITMASK(t) (reloc_target_bitmask[t])
uint32_t
rtems_rtl_elf_section_flags (const rtems_rtl_obj_t* obj,
const Elf_Shdr* shdr)
{
return 0;
}
bool
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
{
@@ -144,6 +153,7 @@ rtems_rtl_elf_relocate_rela (const rtems_rtl_obj_t* obj,
{
Elf_Addr *where;
Elf_Word type, value, mask;
Elf_Addr tmp = 0;
where = (Elf_Addr *) (sect->base + rela->r_offset);
@@ -219,31 +229,32 @@ rtems_rtl_elf_relocate_rela (const rtems_rtl_obj_t* obj,
value &= mask;
if (RELOC_UNALIGNED(type)) {
/* Handle unaligned relocations. */
Elf_Addr tmp = 0;
char *ptr = (char *)where;
/*
* Handle unaligned relocations.
*/
char *ptr = (char*) where;
int i, size = RELOC_TARGET_SIZE (type) / 8;
/* Read it in one byte at a time. */
for (i=0; i<size; i++)
for (i = size - 1; i >= 0; i--)
tmp = (tmp << 8) | ptr[i];
tmp &= ~mask;
tmp |= value;
/* Write it back out. */
for (i=0; i<size; i++)
ptr[i] = ((tmp >> (8*i)) & 0xff);
for (i = size - 1; i >= 0; i--, tmp >>= 8)
ptr[i] = tmp & 0xff;
} else {
*where &= ~mask;
*where |= value;
tmp = *where;
}
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
printf ("rtl: %s %p @ %p in %s\n",
reloc_names[type], (void *)*where, where, rtems_rtl_obj_oname (obj));
reloc_names[ELF_R_TYPE(rela->r_info)],
(void *)tmp, where, rtems_rtl_obj_oname (obj));
return true;
}
@@ -259,3 +270,23 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
printf ("rtl: rel type record not supported; please report\n");
return false;
}
bool
rtems_rtl_elf_unwind_parse (const rtems_rtl_obj_t* obj,
const char* name,
uint32_t flags)
{
return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
}
bool
rtems_rtl_elf_unwind_register (rtems_rtl_obj_t* obj)
{
return rtems_rtl_elf_unwind_dw2_register (obj);
}
bool
rtems_rtl_elf_unwind_deregister (rtems_rtl_obj_t* obj)
{
return rtems_rtl_elf_unwind_dw2_deregister (obj);
}

View File

@@ -10,6 +10,15 @@
#include "rtl-elf.h"
#include "rtl-error.h"
#include "rtl-trace.h"
#include "rtl-unwind.h"
#include "rtl-unwind-dw2.h"
uint32_t
rtems_rtl_elf_section_flags (const rtems_rtl_obj_t* obj,
const Elf_Shdr* shdr)
{
return 0;
}
bool
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
@@ -95,3 +104,23 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
rtems_rtl_set_error (EINVAL, "rel type record not supported");
return false;
}
bool
rtems_rtl_elf_unwind_parse (const rtems_rtl_obj_t* obj,
const char* name,
uint32_t flags)
{
return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
}
bool
rtems_rtl_elf_unwind_register (rtems_rtl_obj_t* obj)
{
return rtems_rtl_elf_unwind_dw2_register (obj);
}
bool
rtems_rtl_elf_unwind_deregister (rtems_rtl_obj_t* obj)
{
return rtems_rtl_elf_unwind_dw2_deregister (obj);
}

View File

@@ -49,14 +49,21 @@
/**
* The table of supported loader formats.
*/
static rtems_rtl_loader_table_t loaders[RTEMS_RTL_ELF_LOADER_COUNT +
RTEMS_RTL_RAP_LOADER_COUNT] =
#define RTEMS_RTL_LOADERS (RTEMS_RTL_ELF_LOADER_COUNT + RTEMS_RTL_RAP_LOADER_COUNT)
static const rtems_rtl_loader_table_t loaders[RTEMS_RTL_LOADERS] =
{
#if RTEMS_RTL_RAP_LOADER
{ rtems_rtl_rap_file_check, rtems_rtl_rap_file_load, rtems_rtl_rap_file_sig },
{ .check = rtems_rtl_rap_file_check,
.load = rtems_rtl_rap_file_load,
.unload = rtems_rtl_rap_file_unload,
.unload = rtems_rtl_rap_file_unload,
.signature = rtems_rtl_rap_file_sig },
#endif
#if RTEMS_RTL_ELF_LOADER
{ rtems_rtl_elf_file_check, rtems_rtl_elf_file_load, rtems_rtl_elf_file_sig },
{ .check = rtems_rtl_elf_file_check,
.load = rtems_rtl_elf_file_load,
.unload = rtems_rtl_elf_file_unload,
.signature = rtems_rtl_elf_file_sig },
#endif
};
@@ -72,6 +79,10 @@ rtems_rtl_obj_alloc (void)
* Initialise the chains.
*/
rtems_chain_initialize_empty (&obj->sections);
/*
* No valid format.
*/
obj->format = -1;
}
return obj;
}
@@ -97,14 +108,14 @@ rtems_rtl_obj_free (rtems_rtl_obj_t* obj)
}
if (!rtems_chain_is_node_off_chain (&obj->link))
rtems_chain_extract (&obj->link);
rtems_rtl_alloc_module_del (&obj->text_base, &obj->const_base,
rtems_rtl_alloc_module_del (&obj->text_base, &obj->const_base, &obj->eh_base,
&obj->data_base, &obj->bss_base);
rtems_rtl_symbol_obj_erase (obj);
rtems_rtl_obj_free_names (obj);
if (obj->sec_num)
free (obj->sec_num);
if (obj->detail)
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, (void*)obj->detail);
if (obj->linkmap)
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, (void*) obj->linkmap);
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, obj);
return true;
}
@@ -238,7 +249,7 @@ rtems_rtl_scan_decimal (const uint8_t* string, size_t len)
static size_t
rtems_rtl_sect_align (size_t offset, uint32_t alignment)
{
if ((alignment > 1) && ((offset & ~alignment) != 0))
if ((alignment > 1) && ((offset & (alignment - 1)) != 0))
offset = (offset + alignment) & ~(alignment - 1);
return offset;
}
@@ -264,12 +275,12 @@ rtems_rtl_obj_sect_summer (rtems_chain_node* node, void* data)
}
static size_t
rtems_rtl_obj_section_size (rtems_rtl_obj_t* obj, uint32_t mask)
rtems_rtl_obj_section_size (const rtems_rtl_obj_t* obj, uint32_t mask)
{
rtems_rtl_obj_sect_summer_t summer;
summer.mask = mask;
summer.size = 0;
rtems_rtl_chain_iterate (&obj->sections,
rtems_rtl_chain_iterate ((rtems_chain_control*) &obj->sections,
rtems_rtl_obj_sect_summer,
&summer);
return summer.size;
@@ -302,12 +313,12 @@ rtems_rtl_obj_sect_aligner (rtems_chain_node* node, void* data)
}
static size_t
rtems_rtl_obj_section_alignment (rtems_rtl_obj_t* obj, uint32_t mask)
rtems_rtl_obj_section_alignment (const rtems_rtl_obj_t* obj, uint32_t mask)
{
rtems_rtl_obj_sect_aligner_t aligner;
aligner.mask = mask;
aligner.alignment = 0;
rtems_rtl_chain_iterate (&obj->sections,
rtems_rtl_chain_iterate ((rtems_chain_control*) &obj->sections,
rtems_rtl_obj_sect_aligner,
&aligner);
return aligner.alignment;
@@ -401,26 +412,30 @@ rtems_rtl_obj_add_section (rtems_rtl_obj_t* obj,
int info,
uint32_t flags)
{
rtems_rtl_obj_sect_t* sect = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
sizeof (rtems_rtl_obj_sect_t), true);
if (!sect)
if (size > 0)
{
rtems_rtl_set_error (ENOMEM, "adding allocated section");
return false;
}
sect->section = section;
sect->name = rtems_rtl_strdup (name);
sect->size = size;
sect->offset = offset;
sect->alignment = alignment;
sect->link = link;
sect->info = info;
sect->flags = flags;
sect->base = NULL;
rtems_chain_append (&obj->sections, &sect->node);
rtems_rtl_obj_sect_t* sect = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
sizeof (rtems_rtl_obj_sect_t),
true);
if (!sect)
{
rtems_rtl_set_error (ENOMEM, "adding allocated section");
return false;
}
sect->section = section;
sect->name = rtems_rtl_strdup (name);
sect->size = size;
sect->offset = offset;
sect->alignment = alignment;
sect->link = link;
sect->info = info;
sect->flags = flags;
sect->base = NULL;
rtems_chain_append (&obj->sections, &sect->node);
if (rtems_rtl_trace (RTEMS_RTL_TRACE_SECTION))
printf ("rtl: sect: %-2d: %s\n", section, name);
if (rtems_rtl_trace (RTEMS_RTL_TRACE_SECTION))
printf ("rtl: sect: %-2d: %s (%zu)\n", section, name, size);
}
return true;
}
@@ -464,12 +479,13 @@ rtems_rtl_obj_sect_match_name (rtems_chain_node* node, void* data)
}
rtems_rtl_obj_sect_t*
rtems_rtl_obj_find_section (rtems_rtl_obj_t* obj, const char* name)
rtems_rtl_obj_find_section (const rtems_rtl_obj_t* obj,
const char* name)
{
rtems_rtl_obj_sect_finder_t match;
match.sect = NULL;
match.name = name;
rtems_rtl_chain_iterate (&obj->sections,
rtems_rtl_chain_iterate ((rtems_chain_control*) &obj->sections,
rtems_rtl_obj_sect_match_name,
&match);
return match.sect;
@@ -489,61 +505,74 @@ rtems_rtl_obj_sect_match_index (rtems_chain_node* node, void* data)
}
rtems_rtl_obj_sect_t*
rtems_rtl_obj_find_section_by_index (rtems_rtl_obj_t* obj, int index)
rtems_rtl_obj_find_section_by_index (const rtems_rtl_obj_t* obj,
int index)
{
rtems_rtl_obj_sect_finder_t match;
match.sect = NULL;
match.index = index;
rtems_rtl_chain_iterate (&obj->sections,
rtems_rtl_chain_iterate ((rtems_chain_control*) &obj->sections,
rtems_rtl_obj_sect_match_index,
&match);
return match.sect;
}
size_t
rtems_rtl_obj_text_size (rtems_rtl_obj_t* obj)
rtems_rtl_obj_text_size (const rtems_rtl_obj_t* obj)
{
return rtems_rtl_obj_section_size (obj, RTEMS_RTL_OBJ_SECT_TEXT);
}
uint32_t
rtems_rtl_obj_text_alignment (rtems_rtl_obj_t* obj)
rtems_rtl_obj_text_alignment (const rtems_rtl_obj_t* obj)
{
return rtems_rtl_obj_section_alignment (obj, RTEMS_RTL_OBJ_SECT_TEXT);
}
size_t
rtems_rtl_obj_const_size (rtems_rtl_obj_t* obj)
rtems_rtl_obj_const_size (const rtems_rtl_obj_t* obj)
{
return rtems_rtl_obj_section_size (obj, RTEMS_RTL_OBJ_SECT_CONST);
}
uint32_t
rtems_rtl_obj_const_alignment (rtems_rtl_obj_t* obj)
rtems_rtl_obj_eh_alignment (const rtems_rtl_obj_t* obj)
{
return rtems_rtl_obj_section_alignment (obj, RTEMS_RTL_OBJ_SECT_EH);
}
size_t
rtems_rtl_obj_eh_size (const rtems_rtl_obj_t* obj)
{
return rtems_rtl_obj_section_size (obj, RTEMS_RTL_OBJ_SECT_EH);
}
uint32_t
rtems_rtl_obj_const_alignment (const rtems_rtl_obj_t* obj)
{
return rtems_rtl_obj_section_alignment (obj, RTEMS_RTL_OBJ_SECT_CONST);
}
size_t
rtems_rtl_obj_data_size (rtems_rtl_obj_t* obj)
rtems_rtl_obj_data_size (const rtems_rtl_obj_t* obj)
{
return rtems_rtl_obj_section_size (obj, RTEMS_RTL_OBJ_SECT_DATA);
}
uint32_t
rtems_rtl_obj_data_alignment (rtems_rtl_obj_t* obj)
rtems_rtl_obj_data_alignment (const rtems_rtl_obj_t* obj)
{
return rtems_rtl_obj_section_alignment (obj, RTEMS_RTL_OBJ_SECT_DATA);
}
size_t
rtems_rtl_obj_bss_size (rtems_rtl_obj_t* obj)
rtems_rtl_obj_bss_size (const rtems_rtl_obj_t* obj)
{
return rtems_rtl_obj_section_size (obj, RTEMS_RTL_OBJ_SECT_BSS);
}
uint32_t
rtems_rtl_obj_bss_alignment (rtems_rtl_obj_t* obj)
rtems_rtl_obj_bss_alignment (const rtems_rtl_obj_t* obj)
{
return rtems_rtl_obj_section_alignment (obj, RTEMS_RTL_OBJ_SECT_BSS);
}
@@ -572,21 +601,25 @@ typedef struct
static bool
rtems_rtl_obj_sect_sync_handler (rtems_chain_node* node, void* data)
{
rtems_rtl_obj_sect_t* sect = (rtems_rtl_obj_sect_t*) node;
rtems_rtl_obj_sect_t* sect = (rtems_rtl_obj_sect_t*) node;
rtems_rtl_obj_sect_sync_ctx_t* sync_ctx = data;
uintptr_t old_end;
uintptr_t new_start;
uintptr_t old_end;
uintptr_t new_start;
if ( !(sect->flags & sync_ctx->mask) || !sect->size)
if ((sect->flags & sync_ctx->mask) == 0 || sect->size == 0)
return true;
if (sync_ctx->end_va == sync_ctx->start_va) {
if (sync_ctx->end_va == sync_ctx->start_va)
{
sync_ctx->start_va = sect->base;
} else {
old_end = (uintptr_t)sync_ctx->end_va & ~(sync_ctx->cache_line_size - 1);
new_start = (uintptr_t)sect->base & ~(sync_ctx->cache_line_size - 1);
if ( (sect->base < sync_ctx->start_va) ||
(new_start - old_end > sync_ctx->cache_line_size) ) {
}
else
{
old_end = (uintptr_t) sync_ctx->end_va & ~(sync_ctx->cache_line_size - 1);
new_start = (uintptr_t) sect->base & ~(sync_ctx->cache_line_size - 1);
if ((sect->base < sync_ctx->start_va) ||
(new_start - old_end > sync_ctx->cache_line_size))
{
rtems_cache_instruction_sync_after_code_change(sync_ctx->start_va,
sync_ctx->end_va - sync_ctx->start_va + 1);
sync_ctx->start_va = sect->base;
@@ -599,7 +632,7 @@ rtems_rtl_obj_sect_sync_handler (rtems_chain_node* node, void* data)
}
void
rtems_rtl_obj_synchronize_cache (rtems_rtl_obj_t* obj)
rtems_rtl_obj_synchronize_cache (rtems_rtl_obj_t* obj)
{
rtems_rtl_obj_sect_sync_ctx_t sync_ctx;
@@ -610,7 +643,7 @@ rtems_rtl_obj_synchronize_cache (rtems_rtl_obj_t* obj)
sync_ctx.mask = RTEMS_RTL_OBJ_SECT_TEXT | RTEMS_RTL_OBJ_SECT_CONST |
RTEMS_RTL_OBJ_SECT_DATA | RTEMS_RTL_OBJ_SECT_BSS |
RTEMS_RTL_OBJ_SECT_EXEC;
RTEMS_RTL_OBJ_SECT_EH | RTEMS_RTL_OBJ_SECT_EXEC;
sync_ctx.start_va = 0;
sync_ctx.end_va = sync_ctx.start_va;
@@ -634,6 +667,87 @@ rtems_rtl_obj_load_symbols (rtems_rtl_obj_t* obj,
return rtems_rtl_obj_section_handler (mask, obj, fd, handler, data);
}
static int
rtems_rtl_obj_sections_linked_to_order (rtems_rtl_obj_t* obj,
int section,
uint32_t visited_mask)
{
rtems_chain_control* sections = &obj->sections;
rtems_chain_node* node = rtems_chain_first (sections);
/*
* Find the section being linked-to. If the linked-to link field is 0 we have
* the end and the section's order is the position we are after.
*/
while (!rtems_chain_is_tail (sections, node))
{
rtems_rtl_obj_sect_t* sect = (rtems_rtl_obj_sect_t*) node;
if (sect->section == section)
{
const uint32_t mask = sect->flags & RTEMS_RTL_OBJ_SECT_TYPES;
int order = 0;
if (sect->link != 0)
{
/*
* Have we already visited this type of section? Avoid nesting for
* ever.
*/
if ((sect->flags & visited_mask) != 0)
{
rtems_rtl_set_error (errno, "section link loop");
return -1;
}
return rtems_rtl_obj_sections_linked_to_order (obj,
sect->link,
visited_mask | mask);
}
node = rtems_chain_first (sections);
while (!rtems_chain_is_tail (sections, node))
{
sect = (rtems_rtl_obj_sect_t*) node;
if ((sect->flags & mask) == mask)
{
if (sect->section == section)
return order;
++order;
}
node = rtems_chain_next (node);
}
}
node = rtems_chain_next (node);
}
rtems_rtl_set_error (errno, "section link not found");
return -1;
}
static void
rtems_rtl_obj_sections_link_order (uint32_t mask, rtems_rtl_obj_t* obj)
{
rtems_chain_control* sections = &obj->sections;
rtems_chain_node* node = rtems_chain_first (sections);
int order = 0;
while (!rtems_chain_is_tail (sections, node))
{
rtems_rtl_obj_sect_t* sect = (rtems_rtl_obj_sect_t*) node;
if ((sect->flags & mask) == mask)
{
/*
* If the section is linked in order find the linked-to section's order
* and move the section in the section list to
*/
if (sect->link == 0)
sect->load_order = order++;
else
{
sect->load_order =
rtems_rtl_obj_sections_linked_to_order (obj,
sect->link,
mask);
}
}
node = rtems_chain_next (node);
}
}
static size_t
rtems_rtl_obj_sections_loader (uint32_t mask,
rtems_rtl_obj_t* obj,
@@ -646,42 +760,54 @@ rtems_rtl_obj_sections_loader (uint32_t mask,
rtems_chain_node* node = rtems_chain_first (sections);
size_t base_offset = 0;
bool first = true;
int order = 0;
while (!rtems_chain_is_tail (sections, node))
{
rtems_rtl_obj_sect_t* sect = (rtems_rtl_obj_sect_t*) node;
if ((sect->size != 0) && ((sect->flags & mask) != 0))
{
if (!first)
base_offset = rtems_rtl_sect_align (base_offset, sect->alignment);
sect->base = base + base_offset;
if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD_SECT))
printf ("rtl: loading: %s -> %8p (%zi)\n",
sect->name, sect->base, sect->size);
if ((sect->flags & RTEMS_RTL_OBJ_SECT_LOAD) == RTEMS_RTL_OBJ_SECT_LOAD)
if (sect->load_order == order)
{
if (!handler (obj, fd, sect, data))
if (!first)
base_offset = rtems_rtl_sect_align (base_offset, sect->alignment);
first = false;
sect->base = base + base_offset;
if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD_SECT))
printf ("rtl: loading:%2d: %s -> %8p (s:%zi f:%04lx a:%lu l:%02d)\n",
order, sect->name, sect->base, sect->size,
sect->flags, sect->alignment, sect->link);
if ((sect->flags & RTEMS_RTL_OBJ_SECT_LOAD) == RTEMS_RTL_OBJ_SECT_LOAD)
{
if (!handler (obj, fd, sect, data))
{
sect->base = 0;
return false;
}
}
else if ((sect->flags & RTEMS_RTL_OBJ_SECT_ZERO) == RTEMS_RTL_OBJ_SECT_ZERO)
{
memset (base + base_offset, 0, sect->size);
}
else
{
sect->base = 0;
rtems_rtl_set_error (errno, "section has no load/clear op");
return false;
}
}
else if ((sect->flags & RTEMS_RTL_OBJ_SECT_ZERO) == RTEMS_RTL_OBJ_SECT_ZERO)
{
memset (base + base_offset, 0, sect->size);
}
else
{
sect->base = 0;
rtems_rtl_set_error (errno, "section has no load op");
return false;
}
base_offset += sect->size;
first = false;
base_offset += sect->size;
++order;
node = rtems_chain_first (sections);
continue;
}
}
node = rtems_chain_next (node);
@@ -698,20 +824,30 @@ rtems_rtl_obj_load_sections (rtems_rtl_obj_t* obj,
{
size_t text_size;
size_t const_size;
size_t eh_size;
size_t data_size;
size_t bss_size;
text_size = rtems_rtl_obj_text_size (obj) + rtems_rtl_obj_const_alignment (obj);
const_size = rtems_rtl_obj_const_size (obj) + rtems_rtl_obj_data_alignment (obj);
const_size = rtems_rtl_obj_const_size (obj) + rtems_rtl_obj_eh_alignment (obj);
eh_size = rtems_rtl_obj_eh_size (obj) + rtems_rtl_obj_data_alignment (obj);
data_size = rtems_rtl_obj_data_size (obj) + rtems_rtl_obj_bss_alignment (obj);
bss_size = rtems_rtl_obj_bss_size (obj);
/*
* Set the sizes held in the object data. We need this for a fast reference.
*/
obj->text_size = text_size;
obj->eh_size = eh_size;
obj->bss_size = bss_size;
/*
* Let the allocator manage the actual allocation. The user can use the
* standard heap or provide a specific allocator with memory protection.
*/
if (!rtems_rtl_alloc_module_new (&obj->text_base, text_size,
&obj->const_base, const_size,
&obj->eh_base, eh_size,
&obj->data_base, data_size,
&obj->bss_base, bss_size))
{
@@ -720,7 +856,7 @@ rtems_rtl_obj_load_sections (rtems_rtl_obj_t* obj,
return false;
}
obj->exec_size = text_size + const_size + data_size + bss_size;
obj->exec_size = text_size + const_size + eh_size + data_size + bss_size;
if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD_SECT))
{
@@ -728,12 +864,22 @@ rtems_rtl_obj_load_sections (rtems_rtl_obj_t* obj,
obj->text_base, text_size, rtems_rtl_obj_text_alignment (obj));
printf ("rtl: load sect: const - b:%p s:%zi a:%" PRIu32 "\n",
obj->const_base, const_size, rtems_rtl_obj_const_alignment (obj));
printf ("rtl: load sect: eh - b:%p s:%zi a:%" PRIu32 "\n",
obj->eh_base, eh_size, rtems_rtl_obj_eh_alignment (obj));
printf ("rtl: load sect: data - b:%p s:%zi a:%" PRIu32 "\n",
obj->data_base, data_size, rtems_rtl_obj_data_alignment (obj));
printf ("rtl: load sect: bss - b:%p s:%zi a:%" PRIu32 "\n",
obj->bss_base, bss_size, rtems_rtl_obj_bss_alignment (obj));
}
/*
* Determine the load order.
*/
rtems_rtl_obj_sections_link_order (RTEMS_RTL_OBJ_SECT_TEXT, obj);
rtems_rtl_obj_sections_link_order (RTEMS_RTL_OBJ_SECT_CONST, obj);
rtems_rtl_obj_sections_link_order (RTEMS_RTL_OBJ_SECT_EH, obj);
rtems_rtl_obj_sections_link_order (RTEMS_RTL_OBJ_SECT_DATA, obj);
/*
* Load all text then data then bss sections in seperate operations so each
* type of section is grouped together.
@@ -742,12 +888,14 @@ rtems_rtl_obj_load_sections (rtems_rtl_obj_t* obj,
obj, fd, obj->text_base, handler, data) ||
!rtems_rtl_obj_sections_loader (RTEMS_RTL_OBJ_SECT_CONST,
obj, fd, obj->const_base, handler, data) ||
!rtems_rtl_obj_sections_loader (RTEMS_RTL_OBJ_SECT_EH,
obj, fd, obj->eh_base, handler, data) ||
!rtems_rtl_obj_sections_loader (RTEMS_RTL_OBJ_SECT_DATA,
obj, fd, obj->data_base, handler, data) ||
!rtems_rtl_obj_sections_loader (RTEMS_RTL_OBJ_SECT_BSS,
obj, fd, obj->bss_base, handler, data))
{
rtems_rtl_alloc_module_del (&obj->text_base, &obj->const_base,
rtems_rtl_alloc_module_del (&obj->text_base, &obj->const_base, &obj->eh_base,
&obj->data_base, &obj->bss_base);
obj->exec_size = 0;
return false;
@@ -972,7 +1120,7 @@ rtems_rtl_obj_archive_find (rtems_rtl_obj_t* obj, int fd)
* name from the table and compare with the name we are after.
*/
#define RTEMS_RTL_MAX_FILE_SIZE (256)
char name[RTEMS_RTL_MAX_FILE_SIZE];
char name[RTEMS_RTL_MAX_FILE_SIZE];
if (!rtems_rtl_seek_read (fd, extended_file_names + extended_off,
RTEMS_RTL_MAX_FILE_SIZE, (uint8_t*) &name[0]))
@@ -1016,7 +1164,7 @@ rtems_rtl_obj_archive_find (rtems_rtl_obj_t* obj, int fd)
return false;
}
bool
static bool
rtems_rtl_obj_file_load (rtems_rtl_obj_t* obj, int fd)
{
int l;
@@ -1024,13 +1172,24 @@ rtems_rtl_obj_file_load (rtems_rtl_obj_t* obj, int fd)
for (l = 0; l < (sizeof (loaders) / sizeof (rtems_rtl_loader_table_t)); ++l)
{
if (loaders[l].check (obj, fd))
{
obj->format = l;
return loaders[l].load (obj, fd);
}
}
rtems_rtl_set_error (ENOENT, "no format loader found");
return false;
}
static bool
rtems_rtl_obj_file_unload (rtems_rtl_obj_t* obj)
{
if (obj->format >= 0 && obj->format < RTEMS_RTL_LOADERS)
return loaders[obj->format].unload (obj);
return false;
}
bool
rtems_rtl_obj_load (rtems_rtl_obj_t* obj)
{
@@ -1057,20 +1216,16 @@ rtems_rtl_obj_load (rtems_rtl_obj_t* obj)
{
if (!rtems_rtl_obj_archive_find (obj, fd))
{
rtems_rtl_obj_caches_flush ();
close (fd);
return false;
}
}
/*
* Call the format specific loader. Currently this is a call to the ELF
* loader. This call could be changed to allow probes then calls if more than
* one format is supported.
* Call the format specific loader.
*/
if (!rtems_rtl_obj_file_load (obj, fd))
{
rtems_rtl_obj_caches_flush ();
close (fd);
return false;
}
@@ -1081,8 +1236,6 @@ rtems_rtl_obj_load (rtems_rtl_obj_t* obj)
return false;
}
rtems_rtl_obj_caches_flush ();
close (fd);
return true;
@@ -1092,6 +1245,6 @@ bool
rtems_rtl_obj_unload (rtems_rtl_obj_t* obj)
{
_rtld_linkmap_delete(obj);
rtems_rtl_symbol_obj_erase (obj);
return rtems_rtl_obj_free (obj);
rtems_rtl_obj_file_unload (obj);
return true;
}

View File

@@ -56,14 +56,20 @@ typedef struct rtems_rtl_loader_format_s
typedef bool (*rtems_rtl_loader_check) (rtems_rtl_obj_t* obj, int fd);
/**
* The type of the format loader handler. This handler loads the specific
* The type of the format loader load handler. This handler loads the specific
* format.
*/
typedef bool (*rtems_rtl_loader_load) (rtems_rtl_obj_t* obj, int fd);
/**
* The type of the format loader handler. This handler loads the specific
* format.
* The type of the format loader unload handler. This handler unloads the
* specific format.
*/
typedef bool (*rtems_rtl_loader_unload) (rtems_rtl_obj_t* obj);
/**
* The type of the format loader signature handler. This handler checks the
* format signature.
*/
typedef rtems_rtl_loader_format_t* (*rtems_rtl_loader_sig) (void);
@@ -72,9 +78,10 @@ typedef rtems_rtl_loader_format_t* (*rtems_rtl_loader_sig) (void);
*/
typedef struct rtems_rtl_loader_table_s
{
rtems_rtl_loader_check check; /**< The check handler. */
rtems_rtl_loader_load load; /**< The loader. */
rtems_rtl_loader_sig signature; /**< The loader's signature. */
rtems_rtl_loader_check check; /**< The check handler. */
rtems_rtl_loader_load load; /**< The loader. */
rtems_rtl_loader_unload unload; /**< The unloader. */
rtems_rtl_loader_sig signature; /**< The loader's signature. */
} rtems_rtl_loader_table_t;
/**
@@ -84,18 +91,30 @@ typedef struct rtems_rtl_loader_table_s
#define RTEMS_RTL_OBJ_SECT_CONST (1 << 1) /**< Section holds program text. */
#define RTEMS_RTL_OBJ_SECT_DATA (1 << 2) /**< Section holds program data. */
#define RTEMS_RTL_OBJ_SECT_BSS (1 << 3) /**< Section holds program bss. */
#define RTEMS_RTL_OBJ_SECT_REL (1 << 4) /**< Section holds relocation records. */
#define RTEMS_RTL_OBJ_SECT_RELA (1 << 5) /**< Section holds relocation addend
#define RTEMS_RTL_OBJ_SECT_EH (1 << 4) /**< Section holds exception data. */
#define RTEMS_RTL_OBJ_SECT_REL (1 << 5) /**< Section holds relocation records. */
#define RTEMS_RTL_OBJ_SECT_RELA (1 << 6) /**< Section holds relocation addend
* records. */
#define RTEMS_RTL_OBJ_SECT_SYM (1 << 6) /**< Section holds symbols. */
#define RTEMS_RTL_OBJ_SECT_STR (1 << 7) /**< Section holds strings. */
#define RTEMS_RTL_OBJ_SECT_ALLOC (1 << 8) /**< Section allocates runtime memory. */
#define RTEMS_RTL_OBJ_SECT_LOAD (1 << 9) /**< Section is loaded from object file. */
#define RTEMS_RTL_OBJ_SECT_WRITE (1 << 10) /**< Section is writable, ie data. */
#define RTEMS_RTL_OBJ_SECT_EXEC (1 << 11) /**< Section is executable. */
#define RTEMS_RTL_OBJ_SECT_ZERO (1 << 12) /**< Section is preset to zero. */
#define RTEMS_RTL_OBJ_SECT_CTOR (1 << 13) /**< Section contains constructors. */
#define RTEMS_RTL_OBJ_SECT_DTOR (1 << 14) /**< Section contains destructors. */
#define RTEMS_RTL_OBJ_SECT_SYM (1 << 7) /**< Section holds symbols. */
#define RTEMS_RTL_OBJ_SECT_STR (1 << 8) /**< Section holds strings. */
#define RTEMS_RTL_OBJ_SECT_ALLOC (1 << 9) /**< Section allocates runtime memory. */
#define RTEMS_RTL_OBJ_SECT_LOAD (1 << 10) /**< Section is loaded from object file. */
#define RTEMS_RTL_OBJ_SECT_WRITE (1 << 11) /**< Section is writable, ie data. */
#define RTEMS_RTL_OBJ_SECT_EXEC (1 << 12) /**< Section is executable. */
#define RTEMS_RTL_OBJ_SECT_ZERO (1 << 13) /**< Section is preset to zero. */
#define RTEMS_RTL_OBJ_SECT_LINK (1 << 14) /**< Section is link-ordered. */
#define RTEMS_RTL_OBJ_SECT_CTOR (1 << 15) /**< Section contains constructors. */
#define RTEMS_RTL_OBJ_SECT_DTOR (1 << 16) /**< Section contains destructors. */
#define RTEMS_RTL_OBJ_SECT_LOCD (1 << 17) /**< Section has been located. */
/**
* Section types mask.
*/
#define RTEMS_RTL_OBJ_SECT_TYPES (RTEMS_RTL_OBJ_SECT_TEXT | \
RTEMS_RTL_OBJ_SECT_CONST | \
RTEMS_RTL_OBJ_SECT_DATA | \
RTEMS_RTL_OBJ_SECT_BSS | \
RTEMS_RTL_OBJ_SECT_EH)
/**
* An object file is made up of sections and the can be more than
@@ -109,13 +128,14 @@ struct rtems_rtl_obj_sect_s
const char* name; /**< The section's name. */
size_t size; /**< The size of the section in memory. */
off_t offset; /**< Offset into the object file. Relative to
* the start of the object file. */
* the start of the object file. */
uint32_t alignment; /**< Alignment of this section. */
int link; /**< Section link field. */
int info; /**< Secfion info field. */
uint32_t flags; /**< The section's flags. */
void* base; /**< The base address of the section in
* memory. */
int load_order; /**< Order we load sections. */
};
/**
@@ -135,6 +155,7 @@ struct rtems_rtl_obj_s
rtems_chain_node link; /**< The node's link in the chain. */
uint32_t flags; /**< The status of the object file. */
uint32_t users; /**< References to the object file. */
int format; /**< The format of the object file. */
const char* fname; /**< The file name for the object. */
const char* oname; /**< The object file name. Can be
* relative. */
@@ -153,26 +174,27 @@ struct rtems_rtl_obj_s
size_t global_size; /**< Global symbol memory usage. */
uint32_t unresolved; /**< The number of unresolved relocations. */
void* text_base; /**< The base address of the text section
* in memory. */
* in memory. */
size_t text_size; /**< The size of the text section. */
void* const_base; /**< The base address of the const section
* in memory. */
* in memory. */
void* eh_base; /**< The base address of the eh section
* in memory. */
size_t eh_size; /**< The size of the eh section. */
void* data_base; /**< The base address of the data section
* in memory. */
* in memory. */
void* bss_base; /**< The base address of the bss section
* in memory. */
* in memory. */
size_t bss_size; /**< The size of the bss section. */
size_t exec_size; /**< The amount of executable memory
* allocated */
* allocated */
void* entry; /**< The entry point of the module. */
uint32_t checksum; /**< The checksum of the text sections. A
* zero means do not checksum. */
void* detail; /**< The file details. It contains the elf file
* detail, mainly including elf file name,
* section offset, section size, which
* elf this section belongs to.*/
* zero means do not checksum. */
uint32_t* sec_num; /**< The sec nums of each obj. */
uint32_t obj_num; /**< The count of elf files in an rtl obj. */
struct link_map* linkmap; /**< For GDB. */
void* loader; /**< The file details specific to a loader. */
};
/**
@@ -257,6 +279,20 @@ static inline bool rtems_rtl_obj_aname_valid (const rtems_rtl_obj_t* obj)
return obj->aname;
}
/**
* Is the address inside the text section?
*
* @param obj The object file.
* @return bool There is an archive name
*/
static inline bool rtems_rtl_obj_text_inside (const rtems_rtl_obj_t* obj,
const void* address)
{
return
(address >= obj->text_base) &&
(address < (obj->text_base + obj->text_size));
}
/**
* Allocate an object structure on the heap.
*
@@ -299,18 +335,6 @@ bool rtems_rtl_parse_name (const char* name,
const char** oname,
off_t* ooffset);
/**
* Load the object file.
*
* @param obj The object file's descriptor.
* @param fd The file descriptor.
* @param load_syms Load symbols.
* @param load_dep Load dependent object files.
* @retval true The load was successful.
* @retval false The load failed. The RTL error has been set.
*/
bool rtems_rtl_obj_file_load (rtems_rtl_obj_t* obj, int fd);
/**
* Check of the name matches the object file's object name.
*
@@ -371,8 +395,8 @@ void rtems_rtl_obj_erase_sections (rtems_rtl_obj_t* obj);
* @retval NULL The section was not found.
* @return rtems_rtl_obj_sect_t* The named section.
*/
rtems_rtl_obj_sect_t* rtems_rtl_obj_find_section (rtems_rtl_obj_t* obj,
const char* name);
rtems_rtl_obj_sect_t* rtems_rtl_obj_find_section (const rtems_rtl_obj_t* obj,
const char* name);
/**
* Find a section given a section's index number.
@@ -382,21 +406,21 @@ rtems_rtl_obj_sect_t* rtems_rtl_obj_find_section (rtems_rtl_obj_t* obj,
* @retval NULL The section was not found.
* @return rtems_rtl_obj_sect_t* The found section.
*/
rtems_rtl_obj_sect_t* rtems_rtl_obj_find_section_by_index (rtems_rtl_obj_t* obj,
int index);
rtems_rtl_obj_sect_t* rtems_rtl_obj_find_section_by_index (const rtems_rtl_obj_t* obj,
int index);
/**
* The text size of the object file. Only use once all the sections has been
* added. It includes alignments between sections that are part of the object's
* text area. The consts sections are included in this section.
* The text section size. Only use once all the sections has been added. It
* includes alignments between sections that are part of the object's text
* area. The consts sections are included in this section.
*
* @param obj The object file's descriptor.
* @return size_t The size of the text area of the object file.
*/
size_t rtems_rtl_obj_text_size (rtems_rtl_obj_t* obj);
size_t rtems_rtl_obj_text_size (const rtems_rtl_obj_t* obj);
/**
* The text section alignment of the object file. Only use once all the
* The text section alignment for the object file. Only use once all the
* sections has been added. The section alignment is the alignment of the first
* text type section loaded the text section.
*
@@ -406,20 +430,20 @@ size_t rtems_rtl_obj_text_size (rtems_rtl_obj_t* obj);
* @param obj The object file's descriptor.
* @return uint32_t The alignment. Can be 0 or 1 for not aligned or the alignment.
*/
uint32_t rtems_rtl_obj_text_alignment (rtems_rtl_obj_t* obj);
uint32_t rtems_rtl_obj_text_alignment (const rtems_rtl_obj_t* obj);
/**
* The const size of the object file. Only use once all the sections has been
* added. It includes alignments between sections that are part of the object's
* const area. The consts sections are included in this section.
* The const section size. Only use once all the sections has been added. It
* includes alignments between sections that are part of the object's const
* area. The consts sections are included in this section.
*
* @param obj The object file's descriptor.
* @return size_t The size of the const area of the object file.
*/
size_t rtems_rtl_obj_const_size (rtems_rtl_obj_t* obj);
size_t rtems_rtl_obj_const_size (const rtems_rtl_obj_t* obj);
/**
* The const section alignment of the object file. Only use once all the
* The const section alignment for the object file. Only use once all the
* sections has been added. The section alignment is the alignment of the first
* const type section loaded the const section.
*
@@ -429,20 +453,42 @@ size_t rtems_rtl_obj_const_size (rtems_rtl_obj_t* obj);
* @param obj The object file's descriptor.
* @return uint32_t The alignment. Can be 0 or 1 for not aligned or the alignment.
*/
uint32_t rtems_rtl_obj_const_alignment (rtems_rtl_obj_t* obj);
uint32_t rtems_rtl_obj_const_alignment (const rtems_rtl_obj_t* obj);
/**
* The data size of the object file. Only use once all the sections has been
* added. It includes alignments between sections that are part of the object's
* data area.
* The eh section size. Only use once all the sections has been added. It
* includes alignments between sections that are part of the object's bss area.
*
* @param obj The object file's descriptor.
* @return size_t The size of the bss area of the object file.
*/
size_t rtems_rtl_obj_eh_size (const rtems_rtl_obj_t* obj);
/**
* The eh section alignment for the object file. Only use once all the sections
* has been added. The section alignment is the alignment of the first bss type
* section loaded the bss section.
*
* You can assume the alignment is a positive integral power of 2 if not 0 or
* 1. If 0 or 1 then there is no alignment.
*
* @param obj The object file's descriptor.
* @return uint32_t The alignment. Can be 0 or 1 for not aligned or the alignment.
*/
uint32_t rtems_rtl_obj_eh_alignment (const rtems_rtl_obj_t* obj);
/**
* The data section size. Only use once all the sections has been added. It
* includes alignments between sections that are part of the object's data
* area.
*
* @param obj The object file's descriptor.
* @return size_t The size of the data area of the object file.
*/
size_t rtems_rtl_obj_data_size (rtems_rtl_obj_t* obj);
size_t rtems_rtl_obj_data_size (const rtems_rtl_obj_t* obj);
/**
* The data section alignment of the object file. Only use once all the
* The data section alignment for the object file. Only use once all the
* sections has been added. The section alignment is the alignment of the first
* data type section loaded the data section.
*
@@ -452,20 +498,19 @@ size_t rtems_rtl_obj_data_size (rtems_rtl_obj_t* obj);
* @param obj The object file's descriptor.
* @return uint32_t The alignment. Can be 0 or 1 for not aligned or the alignment.
*/
uint32_t rtems_rtl_obj_data_alignment (rtems_rtl_obj_t* obj);
uint32_t rtems_rtl_obj_data_alignment (const rtems_rtl_obj_t* obj);
/**
* The bss size of the object file. Only use once all the sections has been
* added. It includes alignments between sections that are part of the object's
* bss area.
* The bss section size. Only use once all the sections has been added. It
* includes alignments between sections that are part of the object's bss area.
*
* @param obj The object file's descriptor.
* @return size_t The size of the bss area of the object file.
*/
size_t rtems_rtl_obj_bss_size (rtems_rtl_obj_t* obj);
size_t rtems_rtl_obj_bss_size (const rtems_rtl_obj_t* obj);
/**
* The bss section alignment of the object file. Only use once all the
* The bss section alignment for the object file. Only use once all the
* sections has been added. The section alignment is the alignment of the first
* bss type section loaded the bss section.
*
@@ -475,7 +520,7 @@ size_t rtems_rtl_obj_bss_size (rtems_rtl_obj_t* obj);
* @param obj The object file's descriptor.
* @return uint32_t The alignment. Can be 0 or 1 for not aligned or the alignment.
*/
uint32_t rtems_rtl_obj_bss_alignment (rtems_rtl_obj_t* obj);
uint32_t rtems_rtl_obj_bss_alignment (const rtems_rtl_obj_t* obj);
/**
* Relocate the object file. The object file's section are parsed for any

View File

@@ -427,20 +427,22 @@ rtems_rtl_rap_relocate (rtems_rtl_rap_t* rap, rtems_rtl_obj_t* obj)
}
/**
* The structure of obj->detail is
* The structure of obj->linkmap is:
*
* |object_detail(0..obj_num)|section_detail(0..sec_num[0..obj_num])|
* obj_name(0..obj_num)|section_name(0..sec_num[0..obj_num])
*
*/
static bool
rtems_rtl_rap_load_details (rtems_rtl_rap_t* rap, rtems_rtl_obj_t* obj)
rtems_rtl_rap_load_linkmap (rtems_rtl_rap_t* rap, rtems_rtl_obj_t* obj)
{
void* detail;
struct link_map* tmp1;
section_detail* tmp2;
uint32_t obj_detail_size;
uint32_t pos = 0;
int i,j;
section_detail* tmp2;
uint32_t obj_detail_size;
uint32_t pos = 0;
int i;
int j;
obj_detail_size = sizeof (struct link_map) * obj->obj_num;
@@ -449,26 +451,31 @@ rtems_rtl_rap_load_details (rtems_rtl_rap_t* rap, rtems_rtl_obj_t* obj)
obj_detail_size += (obj->sec_num[i] * sizeof (section_detail));
}
obj->detail = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
obj_detail_size + rap->strtable_size, true);
detail = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
obj_detail_size + rap->strtable_size, true);
if (!obj->detail)
if (!detail)
{
rap->strtable_size = 0;
rtems_rtl_set_error (ENOMEM, "no memory for obj global syms");
return false;
}
rap->strtable = obj->detail + obj_detail_size;
rap->strtable = detail + obj_detail_size;
/* Read the obj names and section names */
if (!rtems_rtl_obj_comp_read (rap->decomp, rap->strtable,
/*
* Read the obj names and section names
*/
if (!rtems_rtl_obj_comp_read (rap->decomp,
rap->strtable,
rap->strtable_size))
{
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, obj->detail);
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, detail);
return false;
}
obj->linkmap = (struct link_map*) detail;
if (rtems_rtl_trace (RTEMS_RTL_TRACE_DETAIL))
{
if (rap->rpathlen > 0)
@@ -489,7 +496,7 @@ rtems_rtl_rap_load_details (rtems_rtl_rap_t* rap, rtems_rtl_obj_t* obj)
for (i = 0; i < obj->obj_num; ++i)
{
tmp1 = (struct link_map*) (obj->detail) + i;
tmp1 = obj->linkmap + i;
tmp1->name = rap->strtable + pos;
tmp1->sec_num = obj->sec_num[i];
tmp1->rpathlen = rap->rpathlen;
@@ -509,17 +516,17 @@ rtems_rtl_rap_load_details (rtems_rtl_rap_t* rap, rtems_rtl_obj_t* obj)
}
}
tmp2 =(section_detail*) ((struct link_map*) (obj->detail) + obj->obj_num);
tmp2 = (section_detail*) (obj->linkmap + obj->obj_num);
for (i = 0; i < obj->obj_num; ++i)
{
if (rtems_rtl_trace (RTEMS_RTL_TRACE_DETAIL))
{
printf ("File %d: %s\n", i, ((struct link_map*) obj->detail + i)->name);
printf ("Section: %d sections\n",(unsigned int) obj->sec_num[i]);
printf ("File %d: %s\n", i, (obj->linkmap + i)->name);
printf ("Section: %d sections\n", (unsigned int) obj->sec_num[i]);
}
((struct link_map*)obj->detail + i)->sec_detail = tmp2;
obj->linkmap[i].sec_detail = tmp2;
for (j = 0; j < obj->sec_num[i]; ++j)
{
@@ -532,7 +539,8 @@ rtems_rtl_rap_load_details (rtems_rtl_rap_t* rap, rtems_rtl_obj_t* obj)
!rtems_rtl_rap_read_uint32 (rap->decomp, &offset) ||
!rtems_rtl_rap_read_uint32 (rap->decomp, &size))
{
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_SYMBOL, obj->detail);
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_SYMBOL, obj->linkmap);
obj->linkmap = NULL;
return false;
}
@@ -907,7 +915,7 @@ rtems_rtl_rap_file_load (rtems_rtl_obj_t* obj, int fd)
if (rtems_rtl_trace (RTEMS_RTL_TRACE_DETAIL))
printf ("rtl: rap: details: obj_num=%lu\n", obj->obj_num);
if (!rtems_rtl_rap_load_details (&rap, obj))
if (!rtems_rtl_rap_load_linkmap (&rap, obj))
return false;
}
@@ -975,6 +983,13 @@ rtems_rtl_rap_file_load (rtems_rtl_obj_t* obj, int fd)
return true;
}
bool
rtems_rtl_rap_file_unload (rtems_rtl_obj_t* obj)
{
(void) obj;
return true;
}
rtems_rtl_loader_format_t*
rtems_rtl_rap_file_sig (void)
{

View File

@@ -40,6 +40,13 @@ bool rtems_rtl_rap_file_check (rtems_rtl_obj_t* obj, int fd);
*/
bool rtems_rtl_rap_file_load (rtems_rtl_obj_t* obj, int fd);
/**
* The RAP format unload handler.
*
* @param obj The object to unload.
*/
bool rtems_rtl_rap_file_unload (rtems_rtl_obj_t* obj);
/**
* The RAP format signature handler.
*

View File

@@ -25,7 +25,7 @@
* Flag the targets where off_t is 32 bits. This is not a compiler type
* so we can't rely on prerdefines.
*/
#if defined(__m32r__) || defined(__moxie__)
#if defined(__moxie__)
#define PRIdoff_t PRIo32
#else
#define PRIdoff_t PRIo64

View File

@@ -0,0 +1,71 @@
/*
* COPYRIGHT (c) 2012-2016 Chris Johns <chrisj@rtems.org>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
/**
* @file
*
* @ingroup rtems_rtld
*
* @brief RTEMS Run-Time Link Editor
*
* This is the RTL implementation.
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include <stdio.h>
#include <rtems/rtl/rtl.h>
#include "rtl-elf.h"
#include "rtl-error.h"
#include "rtl-unwind.h"
#include "rtl-unwind-dw2.h"
/*
* These interfaces are not exported outside the GCC source.
*/
void __register_frame (void *begin);
void __deregister_frame (void *begin);
bool
rtems_rtl_elf_unwind_dw2_parse (const rtems_rtl_obj_t* obj,
const char* name,
uint32_t flags)
{
return
((flags & RTEMS_RTL_OBJ_SECT_CONST) != 0) &&
((strcmp(name, ".eh_frame") == 0) ||
(strncmp(name, ".gcc_except_table.", sizeof (".gcc_except_table.") - 1) == 0));
}
bool
rtems_rtl_elf_unwind_dw2_register (const rtems_rtl_obj_t* obj)
{
rtems_rtl_obj_sect_t* sect = rtems_rtl_obj_find_section (obj, ".eh_frame");
if (sect != NULL && sect->size > 0 && sect->base != NULL)
{
__register_frame (sect->base);
}
return true;
}
bool rtems_rtl_elf_unwind_dw2_deregister (const rtems_rtl_obj_t* obj)
{
rtems_rtl_obj_sect_t* sect = rtems_rtl_obj_find_section (obj, ".eh_frame");
if (sect != NULL && sect->size > 0 && sect->base != NULL)
{
__deregister_frame (sect->base);
}
return true;
}

View File

@@ -0,0 +1,83 @@
/*
* COPYRIGHT (c) 2016 Chris Johns <chrisj@rtems.org>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
/**
* @file
*
* @ingroup rtems_rtl
*
* @brief RTEMS Run-Time Linker Unwind DWARF Support.
*/
#if !defined (_RTEMS_RTL_UNWIND_DW2_H_)
#define _RTEMS_RTL_UNWIND_DW2_H_
#include "rtl-elf.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#if __SIZEOF_LONG__ >= __SIZEOF_POINTER__
typedef long rtems_rtl_elf_unwind_dw2_sleb128;
typedef unsigned long rtems_rtl_elf_unwind_dw2_uleb128;
#elif __SIZEOF_LONG_LONG__ >= __SIZEOF_POINTER__
typedef long long rtems_rtl_elf_unwind_dw2_sleb128;
typedef unsigned long long rtems_rtl_elf_unwind_dw2_uleb128;
#else
#error No DW2 type available.
#endif
/**
* Architecture specific handler to check if a section contains exception
* handler data..
*
* @param obj The object file.
* @param name The section's name.
* @param uint32 flags The object file's flags.
* @retval true The section contains unwind information.
* @retval false The section does not contain unwind information.
*/
bool rtems_rtl_elf_unwind_dw2_parse (const rtems_rtl_obj_t* obj,
const char* name,
uint32_t flags);
/**
* Architecture specific handler to add an object file's unwind information to
* the base image.
*
* @param obj The object file.
* @retval true The unwind information has been registered.
* @retval false The unwind information could not be registered.
*/
bool rtems_rtl_elf_unwind_dw2_register (const rtems_rtl_obj_t* obj);
/**
* Architecture specific handler to remove an object file's unwind information
* from the base image.
*
* @param obj The object file.
* @retval true The unwind information has been deregistered.
* @retval false The unwind information could not be deregistered.
*/
bool rtems_rtl_elf_unwind_dw2_deregister (const rtems_rtl_obj_t* obj);
/**
* Read signed and unsigned LEB128 values.
*/
const uint8_t* rtems_rtl_elf_unwind_dw2_read_uleb128 (const uint8_t* data,
rtems_rtl_elf_unwind_dw2_uleb128* val);
const uint8_t* rtems_rtl_elf_unwind_dw2_read_sleb128 (const uint8_t* data,
rtems_rtl_elf_unwind_dw2_sleb128* val);
bool rtems_rtl_elf_unwind_dw2_relocate (const Elf_Addr* where, Elf_Word value, Elf_Word mask);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif

63
cpukit/libdl/rtl-unwind.h Normal file
View File

@@ -0,0 +1,63 @@
/*
* COPYRIGHT (c) 2016 Chris Johns <chrisj@rtems.org>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
/**
* @file
*
* @ingroup rtems_rtl
*
* @brief RTEMS Run-Time Linker Unwind Support.
*/
#if !defined (_RTEMS_RTL_UNWIND_H_)
#define _RTEMS_RTL_UNWIND_H_
#include "rtl-elf.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* Architecture specific handler to check if a section contains exception
* handler data..
*
* @param obj The object file.
* @param name The section's name.
* @param uint32 flags The object file's flags.
* @retval true The section contains unwind information.
* @retval false The section does not contain unwind information.
*/
bool rtems_rtl_elf_unwind_parse (const rtems_rtl_obj_t* obj,
const char* name,
uint32_t flags);
/**
* Architecture specific handler to add an object file's unwind information to
* the base image.
*
* @param obj The object file.
* @retval true The unwind information has been registered.
* @retval false The unwind information could not be registered.
*/
bool rtems_rtl_elf_unwind_register (rtems_rtl_obj_t* obj);
/**
* Architecture specific handler to remove an object file's unwind information
* from the base image.
*
* @param obj The object file.
* @retval true The unwind information has been deregistered.
* @retval false The unwind information could not be deregistered.
*/
bool rtems_rtl_elf_unwind_deregister (rtems_rtl_obj_t* obj);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif

View File

@@ -62,6 +62,7 @@
* Static RTL data is returned to the user when the linker is locked.
*/
static rtems_rtl_data_t* rtl;
static bool rtl_data_init;
/**
* Define a default base global symbol loader function that is weak
@@ -94,12 +95,26 @@ rtems_rtl_data_init (void)
rtems_status_code sc;
rtems_id lock;
/*
* We cannot set an error in this code because there is no RTL data to
* hold it.
*/
if (rtl_data_init)
{
rtems_libio_unlock ();
return false;
}
rtl_data_init = true;
/*
* Always in the heap.
*/
rtl = malloc (sizeof (rtems_rtl_data_t));
if (!rtl)
{
rtems_libio_unlock ();
errno = ENOMEM;
return false;
}
@@ -120,6 +135,7 @@ rtems_rtl_data_init (void)
if (sc != RTEMS_SUCCESSFUL)
{
free (rtl);
rtems_libio_unlock ();
return false;
}
@@ -128,6 +144,7 @@ rtems_rtl_data_init (void)
{
rtems_semaphore_delete (lock);
free (rtl);
rtems_libio_unlock ();
return false;
}
@@ -143,6 +160,7 @@ rtems_rtl_data_init (void)
{
rtems_semaphore_delete (lock);
free (rtl);
rtems_libio_unlock ();
return false;
}
@@ -152,6 +170,7 @@ rtems_rtl_data_init (void)
rtems_rtl_symbol_table_close (&rtl->globals);
rtems_semaphore_delete (lock);
free (rtl);
rtems_libio_unlock ();
return false;
}
@@ -162,6 +181,7 @@ rtems_rtl_data_init (void)
rtems_rtl_unresolved_table_close (&rtl->unresolved);
rtems_semaphore_delete (lock);
free (rtl);
rtems_libio_unlock ();
return false;
}
@@ -173,6 +193,7 @@ rtems_rtl_data_init (void)
rtems_rtl_symbol_table_close (&rtl->globals);
rtems_semaphore_delete (lock);
free (rtl);
rtems_libio_unlock ();
return false;
}
@@ -185,6 +206,7 @@ rtems_rtl_data_init (void)
rtems_rtl_symbol_table_close (&rtl->globals);
rtems_semaphore_delete (lock);
free (rtl);
rtems_libio_unlock ();
return false;
}
@@ -198,6 +220,7 @@ rtems_rtl_data_init (void)
rtems_rtl_symbol_table_close (&rtl->globals);
rtems_semaphore_delete (lock);
free (rtl);
rtems_libio_unlock ();
return false;
}
@@ -212,6 +235,7 @@ rtems_rtl_data_init (void)
rtems_rtl_symbol_table_close (&rtl->globals);
rtems_semaphore_delete (lock);
free (rtl);
rtems_libio_unlock ();
return false;
}
@@ -288,7 +312,7 @@ rtems_rtl_obj_caches (rtems_rtl_obj_cache_t** symbols,
}
void
rtems_rtl_obj_caches_flush ()
rtems_rtl_obj_caches_flush (void)
{
if (rtl)
{
@@ -438,6 +462,7 @@ rtems_rtl_load_object (const char* name, int mode)
if (!rtems_rtl_obj_find_file (obj, name))
{
rtems_rtl_obj_free (obj);
rtems_rtl_obj_caches_flush ();
return NULL;
}
@@ -446,9 +471,12 @@ rtems_rtl_load_object (const char* name, int mode)
if (!rtems_rtl_obj_load (obj))
{
rtems_rtl_obj_free (obj);
rtems_rtl_obj_caches_flush ();
return NULL;
}
rtems_rtl_obj_caches_flush ();
rtems_rtl_unresolved_resolve ();
}
@@ -514,6 +542,9 @@ rtems_rtl_unload_object (rtems_rtl_obj_t* obj)
obj->flags &= ~RTEMS_RTL_OBJ_LOCKED;
ok = rtems_rtl_obj_unload (obj);
rtems_rtl_obj_free (obj);
rtems_rtl_obj_caches_flush ();
}
return ok;

View File

@@ -112,7 +112,7 @@ struct rtems_rtl_data_s
};
/**
* Get the RTL data with out locking. This call assmes the RTL is locked.
* Get the RTL data with out locking. This call assumes the RTL is locked.
*
* @return rtems_rtl_data_t* The RTL data after being locked.
* @retval NULL The RTL data is not initialised.

View File

@@ -200,13 +200,12 @@ _fat_block_read(
}
static ssize_t
fat_block_write(
fat_block_write(
fat_fs_info_t *fs_info,
const uint32_t start_blk,
const uint32_t offset,
const uint32_t count,
const void *buf,
const bool overwrite_block)
const void *buf)
{
int rc = RC_OK;
uint32_t bytes_to_write = MIN(count, (fs_info->vol.bytes_per_block - offset));
@@ -215,8 +214,7 @@ static ssize_t
if (0 < bytes_to_write)
{
if ( overwrite_block
|| (bytes_to_write == fs_info->vol.bytes_per_block))
if (bytes_to_write == fs_info->vol.bytes_per_block)
{
rc = fat_buf_access(fs_info, sec_num, FAT_OP_TYPE_GET, &blk_buf);
}
@@ -399,7 +397,6 @@ _fat_block_release(fat_fs_info_t *fs_info)
* offset - offset inside cluster 'start'
* count - count of bytes to write
* buff - buffer provided by user
* overwrite_cluster - true if cluster can get overwritten, false if cluster content must be kept
*
* RETURNS:
* bytes written on success, or -1 if error occured
@@ -411,8 +408,7 @@ fat_cluster_write(
const uint32_t start_cln,
const uint32_t offset,
const uint32_t count,
const void *buff,
const bool overwrite_cluster)
const void *buff)
{
ssize_t rc = RC_OK;
uint32_t bytes_to_write = MIN(count, (fs_info->vol.bpc - offset));
@@ -436,8 +432,7 @@ fat_cluster_write(
cur_blk,
ofs_blk,
c,
&buffer[bytes_written],
overwrite_cluster);
&buffer[bytes_written]);
if (c != ret)
rc = -1;
else

View File

@@ -511,8 +511,7 @@ fat_cluster_write(fat_fs_info_t *fs_info,
uint32_t start_cln,
uint32_t offset,
uint32_t count,
const void *buff,
bool overwrite_cluster);
const void *buff);
ssize_t
fat_sector_write(fat_fs_info_t *fs_info,

View File

@@ -110,12 +110,10 @@ fat_file_open(
/* access "removed-but-still-open" hash table */
rc = _hash_search(fs_info, fs_info->rhash, key, key, &lfat_fd);
lfat_fd = (*fat_fd) = (fat_file_fd_t*)malloc(sizeof(fat_file_fd_t));
lfat_fd = (*fat_fd) = (fat_file_fd_t*)calloc(1, sizeof(fat_file_fd_t));
if ( lfat_fd == NULL )
rtems_set_errno_and_return_minus_one( ENOMEM );
memset(lfat_fd, 0, sizeof(fat_file_fd_t));
lfat_fd->links_num = 1;
lfat_fd->flags &= ~FAT_FILE_REMOVED;
lfat_fd->map.last_cln = FAT_UNDEFINED_VALUE;
@@ -170,11 +168,9 @@ fat_file_update(fat_fs_info_t *fs_info, fat_file_fd_t *fat_fd)
{
int ret_rc = RC_OK;
/*
* if fat-file descriptor is not marked as "removed", synchronize
* size, first cluster number, write time and date fields of the file
*/
if (!FAT_FILE_IS_REMOVED(fat_fd) && FAT_FILE_HAS_META_DATA_CHANGED(fat_fd))
if (!FAT_FILE_IS_REMOVED(fat_fd) &&
FAT_FILE_HAS_META_DATA_CHANGED(fat_fd) &&
!FAT_FD_OF_ROOT_DIR(fat_fd))
{
int rc;
@@ -403,20 +399,18 @@ static bool
* start - offset(in bytes) to write from
* count - count
* buf - buffer provided by user
* file_cln_initial - initial current cluster number of the file
*
* RETURNS:
* number of bytes actually written to the file on success, or -1 if
* error occured (errno set appropriately)
*/
static ssize_t
fat_file_write_fat32_or_non_root_dir(
fat_file_write_fat32_or_non_root_dir(
fat_fs_info_t *fs_info,
fat_file_fd_t *fat_fd,
const uint32_t start,
const uint32_t count,
const uint8_t *buf,
const uint32_t file_cln_initial)
const uint8_t *buf)
{
int rc = RC_OK;
uint32_t cmpltd = 0;
@@ -426,35 +420,27 @@ static ssize_t
uint32_t ofs_cln = start - (start_cln << fs_info->vol.bpc_log2);
uint32_t ofs_cln_save = ofs_cln;
uint32_t bytes_to_write = count;
uint32_t file_cln_cnt;
ssize_t ret;
uint32_t c;
bool overwrite_cluster = false;
rc = fat_file_lseek(fs_info, fat_fd, start_cln, &cur_cln);
if (RC_OK == rc)
{
file_cln_cnt = cur_cln - fat_fd->cln;
while ( (RC_OK == rc)
&& (bytes_to_write > 0))
{
c = MIN(bytes_to_write, (fs_info->vol.bpc - ofs_cln));
if (file_cln_initial < file_cln_cnt)
overwrite_cluster = true;
ret = fat_cluster_write(fs_info,
cur_cln,
ofs_cln,
c,
&buf[cmpltd],
overwrite_cluster);
&buf[cmpltd]);
if (0 > ret)
rc = -1;
if (RC_OK == rc)
{
++file_cln_cnt;
bytes_to_write -= ret;
cmpltd += ret;
save_cln = cur_cln;
@@ -509,7 +495,6 @@ fat_file_write(
uint32_t byte;
uint32_t c = 0;
bool zero_fill = start > fat_fd->fat_file_size;
uint32_t file_cln_initial = fat_fd->map.file_cln;
uint32_t cln;
@@ -543,8 +528,7 @@ fat_file_write(
cln,
byte,
count,
buf,
false);
buf);
if (0 > ret)
rc = -1;
else
@@ -556,8 +540,7 @@ fat_file_write(
fat_fd,
start,
count,
buf,
file_cln_initial);
buf);
if (0 > ret)
rc = -1;
else

View File

@@ -482,6 +482,8 @@ int msdos_get_dotdot_dir_info_cluster_num_and_offset(
int msdos_sync(rtems_libio_t *iop);
uint8_t msdos_lfn_checksum(const void *entry);
#ifdef __cplusplus
}
#endif

View File

@@ -288,7 +288,13 @@ msdos_get_valid_utf16_filename_character (const uint16_t utf16_character)
static char
msdos_get_valid_codepage_filename_character (const uint8_t character)
{
return codepage_valid_char_map[(unsigned int)character];
char c = codepage_valid_char_map[character];
if (c == 0) {
c = '_';
}
return c;
}
static ssize_t
@@ -556,7 +562,6 @@ msdos_filename_utf8_to_short_name_for_save (
size_t name_size = utf8_name_size;
char *dest_ptr = (char*)short_name;
unsigned int i;
char c;
size_t name_size_tmp;
char name_to_format_buf[MSDOS_SHORT_NAME_LEN +1];
@@ -606,10 +611,8 @@ msdos_filename_utf8_to_short_name_for_save (
dest_ptr[0] = '_';
else if ( 0xE5 == *name_ptr )
dest_ptr[0] = 0x05;
else if (0 != (c = msdos_get_valid_codepage_filename_character( *name_ptr ) ) )
dest_ptr[0] = c;
else
dest_ptr[0] = '_';
dest_ptr[0] = msdos_get_valid_codepage_filename_character(*name_ptr);
++name_ptr;
++returned_size;
--name_size;
@@ -617,11 +620,7 @@ msdos_filename_utf8_to_short_name_for_save (
* Validate and assign all other characters of the name part
*/
for (i = 1; i <= 7 && name_size && *name_ptr != '.'; ++i) {
c = msdos_get_valid_codepage_filename_character ( *name_ptr );
if (c != 0)
dest_ptr[i] = c;
else
dest_ptr[i] = '_';
dest_ptr[i] = msdos_get_valid_codepage_filename_character(*name_ptr);
++name_ptr;
++returned_size;
--name_size;
@@ -644,11 +643,7 @@ msdos_filename_utf8_to_short_name_for_save (
* Copy in the extension part of the name, if any.
*/
for (; i <= 10 && name_size ; i++) {
c = msdos_get_valid_codepage_filename_character ( *name_ptr);
if (c != 0)
dest_ptr[i] = c;
else
dest_ptr[i] = '_';
dest_ptr[i] = msdos_get_valid_codepage_filename_character(*name_ptr);
++name_ptr;
++returned_size;
name_size--;

View File

@@ -222,10 +222,10 @@ static int msdos_utf8_normalize_and_fold(
);
if ( result >= 0 ) {
if ( result < unicode_buf_size ) {
if ( result <= unicode_buf_size ) {
unicodes_to_reencode = result;
} else {
unicodes_to_reencode = unicode_buf_size - 1;
unicodes_to_reencode = unicode_buf_size;
eno = ENOMEM;
}

View File

@@ -179,6 +179,8 @@ msdos_creat_node(const rtems_filesystem_location_info_t *parent_loc,
*/
if (type == FAT_DIRECTORY)
{
uint32_t unused;
/* open new directory as fat-file */
rc = fat_file_open(&fs_info->fat, &dir_pos, &fat_fd);
if (rc != RC_OK)
@@ -188,11 +190,19 @@ msdos_creat_node(const rtems_filesystem_location_info_t *parent_loc,
* we opened fat-file for node we just created, so initialize fat-file
* descritor
*/
fat_fd->fat_file_size = 0;
fat_fd->fat_file_type = FAT_DIRECTORY;
fat_fd->size_limit = MSDOS_MAX_DIR_LENGHT;
fat_file_set_ctime_mtime(fat_fd, now);
/* extend it to contain exactly one cluster */
rc = fat_file_extend(&fs_info->fat,
fat_fd,
true,
fs_info->fat.vol.bpc,
&unused);
if (rc != RC_OK)
goto err;
/*
* dot and dotdot entries are identical to new node except the
* names
@@ -226,33 +236,16 @@ msdos_creat_node(const rtems_filesystem_location_info_t *parent_loc,
CT_LE_W((uint16_t )(((parent_fat_fd->cln) & 0xFFFF0000)>>16));
}
/*
* write dot and dotdot entries to new fat-file: currently fat-file
* correspondes to a new node is zero length, so it will be extended
* by one cluster and entries will be written
*/
ret = fat_file_write(&fs_info->fat, fat_fd, 0,
MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE * 2,
(uint8_t *)dot_dotdot);
if (ret < 0)
{
rc = -1;
goto error;
}
/* increment fat-file size by cluster size */
fat_fd->fat_file_size += fs_info->fat.vol.bpc;
/* set up cluster num for dot entry */
*MSDOS_DIR_FIRST_CLUSTER_LOW(DOT_NODE_P(dot_dotdot)) =
CT_LE_W((uint16_t )((fat_fd->cln) & 0x0000FFFF));
*MSDOS_DIR_FIRST_CLUSTER_HI(DOT_NODE_P(dot_dotdot)) =
CT_LE_W((uint16_t )(((fat_fd->cln) & 0xFFFF0000) >> 16));
/* rewrite dot entry */
/* write dot and dotdot entries */
ret = fat_file_write(&fs_info->fat, fat_fd, 0,
MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE,
(uint8_t *)DOT_NODE_P(dot_dotdot));
MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE * 2,
(uint8_t *)dot_dotdot);
if (ret < 0)
{
rc = -1;

View File

@@ -72,7 +72,7 @@ msdos_dir_read(rtems_libio_t *iop, void *buffer, size_t count)
fat_file_fd_t *fat_fd = iop->pathinfo.node_access;
fat_file_fd_t *tmp_fat_fd = NULL;
struct dirent tmp_dirent;
size_t tmp_lfn_len = 0;
size_t lfn_len = 0;
uint16_t *lfn_buf = converter->buffer.data;
char *sfn_buf = converter->buffer.data;
const size_t buf_size = converter->buffer.size;
@@ -85,9 +85,13 @@ msdos_dir_read(rtems_libio_t *iop, void *buffer, size_t count)
uint32_t lfn_start = FAT_FILE_SHORT_NAME;
uint8_t lfn_checksum = 0;
int lfn_entries = 0;
size_t string_size = sizeof(tmp_dirent.d_name);
bool is_first_entry;
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL)
rtems_set_errno_and_return_minus_one(EIO);
/*
* cast start and count - protect against using sizes that are not exact
* multiples of the -dirent- size. These could result in unexpected
@@ -107,11 +111,6 @@ msdos_dir_read(rtems_libio_t *iop, void *buffer, size_t count)
fat_fd->fat_file_size :
fs_info->fat.vol.bpc;
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL)
rtems_set_errno_and_return_minus_one(EIO);
while (count > 0 && cmpltd >= 0)
{
/*
@@ -185,7 +184,7 @@ msdos_dir_read(rtems_libio_t *iop, void *buffer, size_t count)
*/
lfn_entries = (*MSDOS_DIR_ENTRY_TYPE(entry) &
MSDOS_LAST_LONG_ENTRY_MASK);
tmp_lfn_len = 0;
lfn_len = 0;
lfn_checksum = *MSDOS_DIR_LFN_CHECKSUM(entry);
memset (tmp_dirent.d_name, 0, sizeof(tmp_dirent.d_name));
}
@@ -220,7 +219,7 @@ msdos_dir_read(rtems_libio_t *iop, void *buffer, size_t count)
lfn_entries--;
offset_lfn = lfn_entries * MSDOS_LFN_LEN_PER_ENTRY;
tmp_lfn_len += msdos_get_utf16_string_from_long_entry (
lfn_len += msdos_get_utf16_string_from_long_entry (
entry,
&lfn_buf[offset_lfn],
buf_size - offset_lfn,
@@ -281,33 +280,30 @@ msdos_dir_read(rtems_libio_t *iop, void *buffer, size_t count)
*/
if (lfn_start != FAT_FILE_SHORT_NAME)
{
uint8_t cs = 0;
uint8_t* p = (uint8_t*) entry;
int i;
if (lfn_entries == 0 &&
lfn_checksum == msdos_lfn_checksum(entry)) {
size_t len = sizeof(tmp_dirent.d_name) - 1;
for (i = 0; i < 11; i++, p++)
cs = ((cs & 1) ? 0x80 : 0) + (cs >> 1) + *p;
if (lfn_entries || (lfn_checksum != cs))
lfn_start = FAT_FILE_SHORT_NAME;
eno = (*convert_handler->utf16_to_utf8) (
converter,
lfn_buf,
tmp_lfn_len,
(uint8_t*)(&tmp_dirent.d_name[0]),
&string_size);
if (eno == 0) {
tmp_dirent.d_namlen = string_size;
tmp_dirent.d_name[tmp_dirent.d_namlen] = '\0';
}
else {
eno = (*convert_handler->utf16_to_utf8) (
converter,
lfn_buf,
lfn_len,
(uint8_t *) &tmp_dirent.d_name[0],
&len);
if (eno == 0) {
tmp_dirent.d_namlen = len;
tmp_dirent.d_name[len] = '\0';
} else {
lfn_start = FAT_FILE_SHORT_NAME;
}
} else {
lfn_start = FAT_FILE_SHORT_NAME;
}
}
if (lfn_start == FAT_FILE_SHORT_NAME)
{
if (lfn_start == FAT_FILE_SHORT_NAME) {
size_t len = sizeof(tmp_dirent.d_name) - 1;
/*
* convert dir entry from fixed 8+3 format (without dot)
* to 0..8 + 1dot + 0..3 format
@@ -318,13 +314,12 @@ msdos_dir_read(rtems_libio_t *iop, void *buffer, size_t count)
converter,
sfn_buf,
tmp_dirent.d_namlen,
(uint8_t*)(&tmp_dirent.d_name[0]),
&string_size);
(uint8_t *) &tmp_dirent.d_name[0],
&len);
if ( 0 == eno ) {
tmp_dirent.d_namlen = string_size;
tmp_dirent.d_name[tmp_dirent.d_namlen] = '\0';
}
else {
tmp_dirent.d_namlen = len;
tmp_dirent.d_name[len] = '\0';
} else {
cmpltd = -1;
errno = eno;
}

View File

@@ -1204,8 +1204,8 @@ int msdos_format
case FAT_FAT32:
/* FAT entry 0: 0xffffff00|media_type */
FAT_SET_VAL32(tmp_sec,0,0xffffff00|fmt_params.media_code);
/* FAT entry 1: EOC */
FAT_SET_VAL32(tmp_sec,4,FAT_FAT32_EOC);
/* FAT entry 1: Not dirty, no IO error, EOC */
FAT_SET_VAL32(tmp_sec,4,0xc0000000|FAT_FAT32_EOC);
break;
default:

View File

@@ -55,6 +55,23 @@
const char *const MSDOS_DOT_NAME = ". ";
const char *const MSDOS_DOTDOT_NAME = ".. ";
uint8_t
msdos_lfn_checksum(const void *entry)
{
const uint8_t *name;
uint8_t cs;
int i;
name = (const uint8_t *) MSDOS_DIR_NAME(entry);
cs = 0;
for (i = 0; i < MSDOS_SHORT_NAME_LEN; ++i) {
cs = ((cs & 1) ? 0x80 : 0) + (cs >> 1) + name[i];
}
return cs;
}
/* msdos_is_valid_name_char --
* Routine to check the character in a file or directory name.
* The characters support in the short file name are letters,
@@ -99,7 +116,7 @@ msdos_is_valid_name_char(const char ch)
*
*/
static void
msdos_short_name_hex(char* sfn, int num)
msdos_short_name_hex(char* sfn, uint32_t num)
{
static const char* hex = "0123456789ABCDEF";
char* c = MSDOS_DIR_NAME(sfn);
@@ -820,7 +837,12 @@ fat_file_write_file_size(
sec += (fat_fd->dir_pos.sname.ofs >> fs_info->vol.sec_log2);
byte = (fat_fd->dir_pos.sname.ofs & (fs_info->vol.bps - 1));
le_new_length = CT_LE_L((fat_fd->fat_file_size));
if (fat_fd->fat_file_type == FAT_DIRECTORY) {
le_new_length = CT_LE_L(0);
} else {
le_new_length = CT_LE_L(fat_fd->fat_file_size);
}
ret = fat_sector_write(fs_info, sec, byte + MSDOS_FILE_SIZE_OFFSET, 4,
(char *)(&le_new_length));
if ( ret < 0 )
@@ -997,7 +1019,7 @@ msdos_on_entry_found (
char *name_dir_entry,
char *entry,
fat_dir_pos_t *dir_pos,
uint32_t *dir_offset,
uint32_t dir_offset,
const uint32_t dir_entry,
const fat_pos_t *lfn_start
)
@@ -1013,7 +1035,7 @@ msdos_on_entry_found (
rc = fat_file_ioctl(&fs_info->fat,
fat_fd,
F_CLU_NUM,
*dir_offset * bts2rd,
dir_offset * bts2rd,
&dir_pos->sname.cln);
if (rc == RC_OK) {
dir_pos->sname.ofs = dir_entry;
@@ -1219,10 +1241,10 @@ msdos_compare_entry_against_filename (
const uint8_t *entry,
const size_t entry_size,
const uint8_t *filename,
const size_t filename_size_remaining,
const size_t name_len_remaining,
bool *is_matching)
{
ssize_t size_remaining = filename_size_remaining;
ssize_t size_remaining = name_len_remaining;
int eno = 0;
uint8_t entry_normalized[MSDOS_LFN_ENTRY_SIZE_UTF8];
size_t bytes_in_entry_normalized = sizeof ( entry_normalized );
@@ -1248,7 +1270,7 @@ msdos_compare_entry_against_filename (
*is_matching = true;
} else {
*is_matching = false;
size_remaining = filename_size_remaining;
size_remaining = name_len_remaining;
}
}
@@ -1265,6 +1287,18 @@ msdos_compare_entry_against_filename (
return size_remaining;
}
static void
msdos_prepare_for_next_entry(
fat_pos_t *lfn_start,
bool *entry_matched,
ssize_t *name_len_remaining,
size_t name_len_for_compare)
{
lfn_start->cln = FAT_FILE_SHORT_NAME;
*entry_matched = false;
*name_len_remaining = name_len_for_compare;
}
static int
msdos_find_file_in_directory (
const uint8_t *filename_converted,
@@ -1275,28 +1309,27 @@ msdos_find_file_in_directory (
fat_file_fd_t *fat_fd,
const uint32_t bts2rd,
const bool create_node,
const unsigned int fat_entries,
const unsigned int lfn_entries,
char *name_dir_entry,
fat_dir_pos_t *dir_pos,
uint32_t *dir_offset,
uint32_t *empty_space_offset,
uint32_t *empty_space_entry,
uint32_t *empty_space_count)
uint32_t *empty_file_offset,
uint32_t *empty_entry_count)
{
int rc = RC_OK;
ssize_t bytes_read;
uint32_t dir_entry;
fat_pos_t lfn_start;
uint8_t lfn_checksum = 0;
bool entry_matched = false;
bool entry_matched;
bool empty_space_found = false;
uint32_t entries_per_block = bts2rd / MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE;
int lfn_entry = 0;
uint8_t entry_utf8_normalized[MSDOS_LFN_ENTRY_SIZE_UTF8];
size_t bytes_in_entry;
bool filename_matched = false;
ssize_t filename_size_remaining = name_len_for_compare;
ssize_t name_len_remaining;
rtems_dosfs_convert_control *converter = fs_info->converter;
uint32_t dir_offset = 0;
/*
* Scan the directory seeing if the file is present. While
@@ -1304,15 +1337,17 @@ msdos_find_file_in_directory (
* create the entry if the name is not found.
*/
lfn_start.cln = lfn_start.ofs = FAT_FILE_SHORT_NAME;
msdos_prepare_for_next_entry(&lfn_start, &entry_matched,
&name_len_remaining,
name_len_for_compare);
while ( (bytes_read = fat_file_read (&fs_info->fat, fat_fd, (*dir_offset * bts2rd),
while ( (bytes_read = fat_file_read (&fs_info->fat, fat_fd, (dir_offset * bts2rd),
bts2rd, fs_info->cl_buf)) != FAT_EOF
&& rc == RC_OK)
{
bool remainder_empty = false;
#if MSDOS_FIND_PRINT
printf ("MSFS:[2] dir_offset:%li\n", *dir_offset);
printf ("MSFS:[2] dir_offset:%li\n", dir_offset);
#endif
if (bytes_read < MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE)
@@ -1337,20 +1372,19 @@ msdos_find_file_in_directory (
MSDOS_THIS_DIR_ENTRY_AND_REST_EMPTY);
#if MSDOS_FIND_PRINT
printf ("MSFS:[3] re:%i ee:%i do:%li de:%li(%ld)\n",
remainder_empty, entry_empty, *dir_offset,
remainder_empty, entry_empty, dir_offset,
dir_entry, (dir_entry / MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE));
#endif
/*
* Remember where the we are, ie the start, so we can come back
* to here and write the long file name if this is the start of
* a series of empty entries. If empty_space_count is 0 then
* a series of empty entries. If empty_entry_count is 0 then
* we are currently not inside an empty series of entries. It
* is a count of empty entries.
*/
if (*empty_space_count == 0)
if (*empty_entry_count == 0)
{
*empty_space_entry = dir_entry;
*empty_space_offset = *dir_offset;
*empty_file_offset = dir_offset * bts2rd + dir_entry;
}
if (remainder_empty)
@@ -1374,11 +1408,11 @@ msdos_find_file_in_directory (
if ( !empty_space_found
&& rc == RC_OK )
{
*empty_space_count +=
*empty_entry_count +=
entries_per_block - (dir_entry / MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE);
empty_space_found = true;
#if MSDOS_FIND_PRINT
printf ( "MSFS:[3.2] esf:%i esc%"PRIu32"\n", empty_space_found, *empty_space_count );
printf ( "MSFS:[3.2] esf:%i esc%"PRIu32"\n", empty_space_found, *empty_entry_count );
#endif
}
break;
@@ -1390,15 +1424,18 @@ msdos_find_file_in_directory (
/*
* Remainder is not empty so is this entry empty ?
*/
(*empty_space_count)++;
(*empty_entry_count)++;
if (*empty_space_count == (fat_entries + 1))
if (*empty_entry_count == (lfn_entries + 1))
empty_space_found = true;
}
#if MSDOS_FIND_PRINT
printf ("MSFS:[4.1] esc:%li esf:%i\n",
*empty_space_count, empty_space_found);
*empty_entry_count, empty_space_found);
#endif
msdos_prepare_for_next_entry(&lfn_start, &entry_matched,
&name_len_remaining,
name_len_for_compare);
}
else
{
@@ -1410,8 +1447,8 @@ msdos_find_file_in_directory (
*/
if (create_node && !empty_space_found)
{
*empty_space_entry = 0;
*empty_space_count = 0;
*empty_file_offset = 0;
*empty_entry_count = 0;
}
/*
@@ -1421,6 +1458,9 @@ msdos_find_file_in_directory (
if ((*MSDOS_DIR_ATTR(entry) & MSDOS_ATTR_LFN_MASK) ==
MSDOS_ATTR_LFN)
{
bool is_first_lfn_entry =
(lfn_start.cln == FAT_FILE_SHORT_NAME);
/* int o;*/
#if MSDOS_FIND_PRINT
printf ("MSFS:[4.2] lfn:%c entry:%i checksum:%i\n",
@@ -1432,7 +1472,7 @@ msdos_find_file_in_directory (
* If we are not already processing a LFN see if this is
* the first entry of a LFN ?
*/
if (lfn_start.cln == FAT_FILE_SHORT_NAME)
if (is_first_lfn_entry)
{
entry_matched = false;
@@ -1444,23 +1484,10 @@ msdos_find_file_in_directory (
MSDOS_LAST_LONG_ENTRY) == 0)
continue;
/*
* Does the number of entries in the LFN directory
* entry match the number we expect for this
* file name. Note we do not know the number of
* characters in the entry so this is check further
* on when the characters are checked.
*/
if (fat_entries != (*MSDOS_DIR_ENTRY_TYPE(entry) &
MSDOS_LAST_LONG_ENTRY_MASK))
continue;
/*
* Get the checksum of the short entry.
*/
lfn_start.cln = *dir_offset;
lfn_start.cln = dir_offset;
lfn_start.ofs = dir_entry;
lfn_entry = fat_entries;
lfn_entry = (*MSDOS_DIR_ENTRY_TYPE(entry)
& MSDOS_LAST_LONG_ENTRY_MASK);
lfn_checksum = *MSDOS_DIR_LFN_CHECKSUM(entry);
#if MSDOS_FIND_PRINT
@@ -1482,7 +1509,10 @@ msdos_find_file_in_directory (
#if MSDOS_FIND_PRINT
printf ("MSFS:[4.4] no match\n");
#endif
lfn_start.cln = FAT_FILE_SHORT_NAME;
msdos_prepare_for_next_entry(&lfn_start,
&entry_matched,
&name_len_remaining,
name_len_for_compare);
continue;
}
#if MSDOS_FIND_PRINT
@@ -1493,26 +1523,29 @@ msdos_find_file_in_directory (
bytes_in_entry = msdos_long_entry_to_utf8_name (
converter,
entry,
(lfn_entry + 1) == fat_entries,
is_first_lfn_entry,
&entry_utf8_normalized[0],
sizeof (entry_utf8_normalized));
if (bytes_in_entry > 0) {
filename_size_remaining = msdos_compare_entry_against_filename (
name_len_remaining = msdos_compare_entry_against_filename (
converter,
&entry_utf8_normalized[0],
bytes_in_entry,
&filename_converted[0],
filename_size_remaining,
name_len_remaining,
&entry_matched);
if (filename_size_remaining < 0
|| (! entry_matched)) {
filename_size_remaining = name_len_for_compare;
lfn_start.cln = FAT_FILE_SHORT_NAME;
if (name_len_remaining < 0 || !entry_matched) {
msdos_prepare_for_next_entry(&lfn_start,
&entry_matched,
&name_len_remaining,
name_len_for_compare);
}
} else {
lfn_start.cln = FAT_FILE_SHORT_NAME;
entry_matched = false;
msdos_prepare_for_next_entry(&lfn_start,
&entry_matched,
&name_len_remaining,
name_len_for_compare);
}
}
else
@@ -1530,16 +1563,14 @@ msdos_find_file_in_directory (
*/
if (entry_matched)
{
uint8_t cs = 0;
uint8_t* p = (uint8_t*) MSDOS_DIR_NAME(entry);
int i;
for (i = 0; i < MSDOS_SHORT_NAME_LEN; i++, p++)
cs = ((cs & 1) ? 0x80 : 0) + (cs >> 1) + *p;
if (lfn_entry || (lfn_checksum != cs))
entry_matched = false;
else {
if (lfn_entry ||
name_len_remaining > 0 ||
lfn_checksum != msdos_lfn_checksum(entry)) {
msdos_prepare_for_next_entry(&lfn_start,
&entry_matched,
&name_len_remaining,
name_len_for_compare);
} else if (name_len_remaining == 0) {
filename_matched = true;
rc = msdos_on_entry_found (
fs_info,
@@ -1556,9 +1587,10 @@ msdos_find_file_in_directory (
#if MSDOS_FIND_PRINT
printf ("MSFS:[9.2] checksum, entry_matched:%i, lfn_entry:%i, lfn_checksum:%02x/%02x\n",
entry_matched, lfn_entry, lfn_checksum, cs);
entry_matched, lfn_entry, lfn_checksum, msdos_lfn_checksum(entry));
#endif
} else {
} else if ((*MSDOS_DIR_ATTR(entry) & MSDOS_ATTR_VOLUME_ID)
== 0) {
bytes_in_entry = MSDOS_SHORT_NAME_LEN + 1;
bytes_in_entry = msdos_short_entry_to_utf8_name (
converter,
@@ -1566,14 +1598,14 @@ msdos_find_file_in_directory (
&entry_utf8_normalized[0],
bytes_in_entry);
if (bytes_in_entry > 0) {
filename_size_remaining = msdos_compare_entry_against_filename (
name_len_remaining = msdos_compare_entry_against_filename (
converter,
&entry_utf8_normalized[0],
bytes_in_entry,
&filename_converted[0],
name_len_for_compare,
&entry_matched);
if (entry_matched && filename_size_remaining == 0) {
if (entry_matched && name_len_remaining == 0) {
filename_matched = true;
rc = msdos_on_entry_found (
fs_info,
@@ -1587,15 +1619,17 @@ msdos_find_file_in_directory (
&lfn_start
);
}
if (rc == RC_OK && (! filename_matched)) {
lfn_start.cln = FAT_FILE_SHORT_NAME;
entry_matched = false;
filename_size_remaining = name_len_for_compare;
if (rc == RC_OK && !filename_matched) {
msdos_prepare_for_next_entry(&lfn_start,
&entry_matched,
&name_len_remaining,
name_len_for_compare);
}
} else {
lfn_start.cln = FAT_FILE_SHORT_NAME;
entry_matched = false;
filename_size_remaining = name_len_for_compare;
msdos_prepare_for_next_entry(&lfn_start,
&entry_matched,
&name_len_remaining,
name_len_for_compare);
}
}
}
@@ -1605,7 +1639,7 @@ msdos_find_file_in_directory (
if (filename_matched || remainder_empty)
break;
(*dir_offset)++;
dir_offset++;
}
if ( ! filename_matched ) {
/*
@@ -1615,14 +1649,28 @@ msdos_find_file_in_directory (
rc = MSDOS_NAME_NOT_FOUND_ERR;
#if MSDOS_FIND_PRINT
printf ( "MSFS:[8.1] WRITE do:%"PRIu32" esc:%"PRIu32" eso:%"PRIu32" ese:%"PRIu32"\n",
*dir_offset, *empty_space_count, *empty_space_offset, *empty_space_entry );
printf ( "MSFS:[8.1] WRITE do:%"PRIu32" esc:%"PRIu32" efo:%"PRIu32"\n",
dir_offset, *empty_entry_count, *empty_file_offset );
#endif
}
return rc;
}
static int
msdos_get_pos(
msdos_fs_info_t *fs_info,
fat_file_fd_t *fat_fd,
uint32_t bts2rd,
uint32_t file_offset,
fat_pos_t *pos
)
{
pos->ofs = file_offset & (bts2rd - 1);
return fat_file_ioctl(&fs_info->fat, fat_fd, F_CLU_NUM,
file_offset, &pos->cln);
}
static int
msdos_add_file (
const char *name_converted,
@@ -1630,263 +1678,161 @@ msdos_add_file (
msdos_fs_info_t *fs_info,
fat_file_fd_t *fat_fd,
const uint32_t bts2rd,
const unsigned int fat_entries,
const unsigned int lfn_entries,
const char *name_dir_entry,
fat_dir_pos_t *dir_pos,
const uint32_t dir_offset,
const uint32_t empty_space_offset_param,
const uint32_t empty_space_entry_param,
const uint32_t empty_space_count
uint32_t empty_file_offset,
const uint32_t empty_entry_count
)
{
int ret = 0;
ssize_t bytes_written = 0;
uint8_t lfn_checksum = 0;
uint32_t empty_space_offset = empty_space_offset_param;
uint32_t empty_space_entry = empty_space_entry_param;
bool read_cluster = false;
int lfn_entry = 0;
fat_pos_t lfn_start;
uint32_t dir_entry;
int ret;
ssize_t bytes_written;
uint8_t lfn_checksum;
int lfn_entry;
uint8_t *entry;
uint32_t short_file_offset;
uint32_t length;
/*
* If a long file name calculate the checksum of the short file name
* data to place in each long file name entry. First set the short
* file name to the slot of the SFN entry. This will mean no clashes
* in this directory.
* If there is not enough space available then extend the file.
*/
if (empty_entry_count < lfn_entries + 1)
{
uint32_t unused;
empty_file_offset = fat_fd->fat_file_size -
empty_entry_count * MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE;
ret = fat_file_extend(&fs_info->fat,
fat_fd,
true,
fat_fd->fat_file_size + fs_info->fat.vol.bpc,
&unused);
if (ret != RC_OK)
return ret;
}
if (name_type == MSDOS_NAME_LONG)
{
int slot = (((empty_space_offset * bts2rd) + empty_space_entry) /
MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE) + fat_entries + 1;
uint32_t slot;
/*
* If a long file name calculate the checksum of the short file name
* data to place in each long file name entry. First set the short
* file name to the slot of the SFN entry. This will mean no clashes
* in this directory.
*/
slot = (empty_file_offset /
MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE) + lfn_entries + 1;
msdos_short_name_hex(MSDOS_DIR_NAME(name_dir_entry), slot);
lfn_checksum = msdos_lfn_checksum(name_dir_entry);
short_file_offset = empty_file_offset + lfn_entries
* MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE;
/* Get position of first long file name entry */
ret = msdos_get_pos(fs_info, fat_fd, bts2rd, empty_file_offset,
&dir_pos->lname);
if (ret != RC_OK)
return ret;
} else {
lfn_checksum = 0;
short_file_offset = empty_file_offset;
dir_pos->lname.cln = FAT_FILE_SHORT_NAME;
dir_pos->lname.ofs = FAT_FILE_SHORT_NAME;
}
if (fat_entries)
{
uint8_t* p = (uint8_t*) MSDOS_DIR_NAME(name_dir_entry);
int i;
for (i = 0; i < 11; i++, p++)
lfn_checksum =
((lfn_checksum & 1) ? 0x80 : 0) + (lfn_checksum >> 1) + *p;
}
/*
* If there is no space available then extend the file. The
* empty_space_count is a count of empty entries in the currently
* read cluster so if 0 there is no space. Note, dir_offset will
* be at the next cluster so we can just make empty_space_offset
* that value.
*/
if (empty_space_count == 0)
{
read_cluster = true;
empty_space_offset = dir_offset;
empty_space_entry = 0;
}
/*
* Have we read past the empty block ? If so go back and read it again.
*/
if (dir_offset != empty_space_offset)
read_cluster = true;
/* Get position of short file name entry */
ret = msdos_get_pos(fs_info, fat_fd, bts2rd, short_file_offset,
&dir_pos->sname);
/*
* Handle the entry writes.
*/
lfn_start.cln = lfn_start.ofs = FAT_FILE_SHORT_NAME;
lfn_entry = 0;
entry = fs_info->cl_buf;
#if MSDOS_FIND_PRINT
printf ("MSFS:[9] read_cluster:%d eso:%ld ese:%ld\n",
read_cluster, empty_space_offset, empty_space_entry);
printf ("MSFS:[9] read_cluster:%d efo:%ld ese:%ld\n",
read_cluster, empty_file_offset, empty_space_entry);
#endif
/*
* The one more is the short entry.
*/
while (lfn_entry < (fat_entries + 1))
{
int length = 0;
/* Long file name entries */
for (lfn_entry = 0; lfn_entry < lfn_entries; ++lfn_entry) {
uint8_t *p;
const uint8_t *n;
int i;
uint8_t fill = 0;
if (read_cluster)
/*
* Clear the entry before loading the data.
*/
memset (entry, 0, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE);
*MSDOS_DIR_LFN_CHECKSUM(entry) = lfn_checksum;
p = entry + 1;
n = (const uint8_t *) name_converted +
(lfn_entries - lfn_entry - 1) * MSDOS_LFN_ENTRY_SIZE;
#if MSDOS_FIND_PRINT
printf ("MSFS:[11] ");
#endif
for (i = 0; i < MSDOS_LFN_LEN_PER_ENTRY; ++i)
{
uint32_t new_length;
#if MSDOS_FIND_PRINT
printf ("MSFS:[9.1] eso:%li\n", empty_space_offset);
#endif
ret = fat_file_read(&fs_info->fat, fat_fd,
(empty_space_offset * bts2rd), bts2rd,
fs_info->cl_buf);
if (ret != bts2rd)
if (*n != 0 || *(n + 1) != 0)
{
if (ret != FAT_EOF)
rtems_set_errno_and_return_minus_one(EIO);
#if MSDOS_FIND_PRINT
printf ("MSFS:[9.2] extending file:%li\n", empty_space_offset);
#endif
ret = fat_file_extend (&fs_info->fat, fat_fd, false,
empty_space_offset * bts2rd, &new_length);
if (ret != RC_OK)
return ret;
#if MSDOS_FIND_PRINT
printf ("MSFS:[9.3] extended: %"PRIu32" <-> %"PRIu32"\n", new_length, empty_space_offset * bts2rd);
#endif
if (new_length != (empty_space_offset * bts2rd))
rtems_set_errno_and_return_minus_one(EIO);
memset(fs_info->cl_buf, 0, bts2rd);
bytes_written = fat_file_write(&fs_info->fat, fat_fd,
empty_space_offset * bts2rd,
bts2rd, fs_info->cl_buf);
#if MSDOS_FIND_PRINT
printf ("MSFS:[9.4] clear write: %d\n", ret);
#endif
if (bytes_written == -1)
return -1;
else if (bytes_written != bts2rd)
rtems_set_errno_and_return_minus_one(EIO);
}
}
#if MSDOS_FIND_PRINT
printf ("MSFS:[10] eso:%li\n", empty_space_offset);
#endif
for (dir_entry = empty_space_entry;
dir_entry < bts2rd;
dir_entry += MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE)
{
char* entry = (char*) fs_info->cl_buf + dir_entry;
char* p;
const char* n;
int i;
char fill = 0;
length += MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE;
lfn_entry++;
#if MSDOS_FIND_PRINT
printf ("MSFS:[10] de:%li(%li) length:%i lfn_entry:%i\n",
dir_entry, (dir_entry / MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE),
length, lfn_entry);
#endif
/*
* Time to write the short file name entry.
*/
if (lfn_entry == (fat_entries + 1))
{
/* get current cluster number */
ret = fat_file_ioctl(&fs_info->fat, fat_fd, F_CLU_NUM,
empty_space_offset * bts2rd,
&dir_pos->sname.cln);
if (ret != RC_OK)
return ret;
dir_pos->sname.ofs = dir_entry;
if (lfn_start.cln != FAT_FILE_SHORT_NAME)
{
ret = fat_file_ioctl(&fs_info->fat, fat_fd, F_CLU_NUM,
lfn_start.cln * bts2rd,
&lfn_start.cln);
if (ret != RC_OK)
return ret;
}
dir_pos->lname.cln = lfn_start.cln;
dir_pos->lname.ofs = lfn_start.ofs;
/* write new node entry */
memcpy (entry, (uint8_t *) name_dir_entry,
MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE);
break;
}
/*
* This is a long file name and we need to write
* a long file name entry. See if this is the
* first entry written and if so remember the
* the location of the long file name.
*/
if (lfn_start.cln == FAT_FILE_SHORT_NAME)
{
lfn_start.cln = empty_space_offset;
lfn_start.ofs = dir_entry;
}
/*
* Clear the entry before loading the data.
*/
memset (entry, 0, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE);
*MSDOS_DIR_LFN_CHECKSUM(entry) = lfn_checksum;
p = entry + 1;
n = name_converted + (fat_entries - lfn_entry) * MSDOS_LFN_ENTRY_SIZE;
#if MSDOS_FIND_PRINT
printf ("MSFS:[11] ");
#endif
for (i = 0; i < MSDOS_LFN_LEN_PER_ENTRY; ++i)
{
if (!(*n == 0 && *(n+1) == 0))
{
*p = *n;
*(p+1) = *(n+1);
}
else
{
p [0] = fill;
p [1] = fill;
fill = 0xff;
}
*p = *n;
*(p + 1) = *(n + 1);
n += MSDOS_NAME_LFN_BYTES_PER_CHAR;
#if MSDOS_FIND_PRINT
printf ( "'%c''%c'", *p, *(p+1) );
#endif
switch (i)
{
case 4:
p += 5;
break;
case 10:
p += 4;
break;
default:
p += 2;
break;
}
}
else
{
p [0] = fill;
p [1] = fill;
fill = 0xff;
}
#if MSDOS_FIND_PRINT
printf ( "\n" );
printf ( "'%c''%c'", *p, *(p+1) );
#endif
*MSDOS_DIR_ENTRY_TYPE(entry) = (fat_entries - lfn_entry) + 1;
if (lfn_entry == 1)
*MSDOS_DIR_ENTRY_TYPE(entry) |= MSDOS_LAST_LONG_ENTRY;
*MSDOS_DIR_ATTR(entry) |= MSDOS_ATTR_LFN;
switch (i)
{
case 4:
p += 5;
break;
case 10:
p += 4;
break;
default:
p += 2;
break;
}
}
#if MSDOS_FIND_PRINT
printf ( "\n" );
#endif
*MSDOS_DIR_ENTRY_TYPE(entry) = lfn_entries - lfn_entry;
if (lfn_entry == 0)
*MSDOS_DIR_ENTRY_TYPE(entry) |= MSDOS_LAST_LONG_ENTRY;
*MSDOS_DIR_ATTR(entry) |= MSDOS_ATTR_LFN;
bytes_written = fat_file_write(&fs_info->fat, fat_fd,
(empty_space_offset * bts2rd) + empty_space_entry,
length, fs_info->cl_buf + empty_space_entry);
if (bytes_written == -1)
return -1;
else if (bytes_written != length)
rtems_set_errno_and_return_minus_one(EIO);
empty_space_offset++;
empty_space_entry = 0;
read_cluster = true;
entry += MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE;
}
return ret;
/* Short file name entry */
memcpy(entry, name_dir_entry, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE);
length = (lfn_entries + 1) * MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE;
bytes_written = fat_file_write(&fs_info->fat, fat_fd,
empty_file_offset,
length, fs_info->cl_buf);
if (bytes_written == (ssize_t) length)
return 0;
else if (bytes_written == -1)
return -1;
else
rtems_set_errno_and_return_minus_one(EIO);
}
int
@@ -1905,11 +1851,9 @@ msdos_find_name_in_fat_file (
ssize_t name_len_for_save;
ssize_t name_len_for_compare;
uint32_t bts2rd = 0;
uint32_t empty_space_offset = 0;
uint32_t empty_space_entry = 0;
uint32_t empty_space_count = 0;
uint32_t dir_offset = 0;
unsigned int fat_entries;
uint32_t empty_file_offset = 0;
uint32_t empty_entry_count = 0;
unsigned int lfn_entries;
rtems_dosfs_convert_control *converter = fs_info->converter;
void *buffer = converter->buffer.data;
size_t buffer_size = converter->buffer.size;
@@ -1935,7 +1879,7 @@ msdos_find_name_in_fat_file (
buffer,
MSDOS_SHORT_NAME_LEN);
if (name_len_for_compare > 0) {
fat_entries = 0;
lfn_entries = 0;
}
else
retval = -1;
@@ -1948,7 +1892,7 @@ msdos_find_name_in_fat_file (
buffer,
buffer_size);
if (name_len_for_save > 0) {
fat_entries = (name_len_for_save + MSDOS_LFN_ENTRY_SIZE - 1)
lfn_entries = (name_len_for_save + MSDOS_LFN_ENTRY_SIZE - 1)
/ MSDOS_LFN_ENTRY_SIZE;
name_len_for_compare = msdos_filename_utf8_to_long_name_for_compare (
converter,
@@ -1979,13 +1923,11 @@ msdos_find_name_in_fat_file (
fat_fd,
bts2rd,
create_node,
fat_entries,
lfn_entries,
name_dir_entry,
dir_pos,
&dir_offset,
&empty_space_offset,
&empty_space_entry,
&empty_space_count);
&empty_file_offset,
&empty_entry_count);
}
/* Create a non-existing file/directory if requested */
if ( retval == RC_OK
@@ -1999,7 +1941,7 @@ msdos_find_name_in_fat_file (
buffer,
MSDOS_SHORT_NAME_LEN);
if (name_len_for_save > 0 ) {
fat_entries = 0;
lfn_entries = 0;
}
else
retval = -1;
@@ -2012,7 +1954,7 @@ msdos_find_name_in_fat_file (
buffer,
buffer_size);
if (name_len_for_save > 0) {
fat_entries = (name_len_for_save + MSDOS_LFN_ENTRY_SIZE - 1)
lfn_entries = (name_len_for_save + MSDOS_LFN_ENTRY_SIZE - 1)
/ MSDOS_LFN_ENTRY_SIZE;
}
else
@@ -2031,13 +1973,11 @@ msdos_find_name_in_fat_file (
fs_info,
fat_fd,
bts2rd,
fat_entries,
lfn_entries,
name_dir_entry,
dir_pos,
dir_offset,
empty_space_offset,
empty_space_entry,
empty_space_count
empty_file_offset,
empty_entry_count
);
}

View File

@@ -188,9 +188,10 @@ static int IMFS_memfile_extend(
offset = 0;
}
} else {
for ( ; block>=old_blocks ; block-- ) {
for ( ; block>old_blocks ; block-- ) {
IMFS_memfile_remove_block( memfile, block );
}
IMFS_memfile_remove_block( memfile, old_blocks );
rtems_set_errno_and_return_minus_one( ENOSPC );
}
}

View File

@@ -1019,7 +1019,7 @@ rtems_status_code status;
initialised = 1;
fprintf(stderr,
"RTEMS-NFS $Release$, " \
"RTEMS-NFS, " \
"Till Straumann, Stanford/SLAC/SSRL 2002, " \
"See LICENSE file for licensing info.\n");

View File

@@ -958,7 +958,7 @@ int noblock = 1;
struct sockwakeup wkup;
if (ourSock < 0) {
fprintf(stderr,"RTEMS-RPCIOD $Release$, " \
fprintf(stderr,"RTEMS-RPCIOD, " \
"Till Straumann, Stanford/SLAC/SSRL 2002, " \
"See LICENSE file for licensing info.\n");

View File

@@ -397,7 +397,6 @@ rtems_rfs_buffer_sync (rtems_rfs_file_system* fs)
rtems_status_text (sc));
result = EIO;
}
rtems_disk_release (fs->disk);
#else
if (fsync (fs->device) < 0)
{

View File

@@ -11,24 +11,9 @@
#include "shell.h"
struct rtems_shell_topic_tt;
typedef struct rtems_shell_topic_tt rtems_shell_topic_t;
struct rtems_shell_topic_tt {
const char *topic;
rtems_shell_topic_t *next;
};
extern rtems_shell_cmd_t * rtems_shell_first_cmd;
extern rtems_shell_topic_t * rtems_shell_first_topic;
rtems_shell_topic_t * rtems_shell_lookup_topic(const char *topic);
bool rtems_shell_can_see_cmd(const rtems_shell_cmd_t *shell_cmd);
int rtems_shell_execute_cmd(const char *cmd, int argc, char *argv[]);
extern void rtems_shell_register_monitor_commands(void);
extern void rtems_shell_print_heap_info(

View File

@@ -60,7 +60,7 @@ static int rtems_shell_main_mfill(
/*
* Now fill the memory.
*/
memset(addr, size, value);
memset(addr, value, size);
return 0;
}

View File

@@ -40,22 +40,44 @@
#include <pthread.h>
#include <assert.h>
#define SHELL_STD_DEBUG 0
#if SHELL_STD_DEBUG
#include <rtems/bspIo.h>
#define shell_std_debug(...) \
do { printk("shell[%08x]: ", rtems_task_self()); printk(__VA_ARGS__); } while (0)
#else
#define shell_std_debug(...)
#endif
const rtems_shell_env_t rtems_global_shell_env = {
.magic = rtems_build_name('S', 'E', 'N', 'V'),
.managed = false,
.devname = CONSOLE_DEVICE_NAME,
.taskname = "SHGL",
.exit_shell = false,
.forever = true,
.errorlevel = -1,
.echo = false,
.cwd = "/",
.input = NULL,
.output = NULL,
.output_append = false,
.parent_stdin = NULL,
.parent_stdout = NULL,
.parent_stderr = NULL,
.wake_on_end = RTEMS_ID_NONE,
.login_check = NULL
.exit_code = NULL,
.login_check = NULL,
.uid = 0,
.gid = 0
};
typedef struct rtems_shell_env_key_handle
{
bool managed;
rtems_shell_env_t* env;
} rtems_shell_env_key_handle;
static pthread_once_t rtems_shell_once = PTHREAD_ONCE_INIT;
static pthread_key_t rtems_shell_current_env_key;
@@ -64,7 +86,7 @@ static pthread_key_t rtems_shell_current_env_key;
* Initialize the shell user/process environment information
*/
static rtems_shell_env_t *rtems_shell_init_env(
rtems_shell_env_t *shell_env_p
rtems_shell_env_t *shell_env_parent
)
{
rtems_shell_env_t *shell_env;
@@ -72,11 +94,16 @@ static rtems_shell_env_t *rtems_shell_init_env(
shell_env = malloc(sizeof(rtems_shell_env_t));
if ( !shell_env )
return NULL;
if ( !shell_env_p ) {
if ( shell_env_parent == NULL ) {
shell_env_parent = rtems_shell_get_current_env();
}
if ( shell_env_parent == NULL ) {
*shell_env = rtems_global_shell_env;
} else {
*shell_env = *shell_env_p;
*shell_env = *shell_env_parent;
}
shell_env->managed = true;
shell_env->taskname = NULL;
return shell_env;
@@ -89,17 +116,20 @@ static void rtems_shell_env_free(
void *ptr
)
{
rtems_shell_env_t *shell_env;
shell_env = (rtems_shell_env_t *) ptr;
if ( ptr != NULL ) {
rtems_shell_env_key_handle *handle = (rtems_shell_env_key_handle *) ptr;
rtems_shell_env_t *shell_env = handle->env;
if ( !ptr )
return;
if ( handle->managed ) {
if ( shell_env->input )
free((void *)shell_env->input);
if ( shell_env->output )
free((void *)shell_env->output);
free( shell_env );
}
if ( shell_env->input )
free((void *)shell_env->input);
if ( shell_env->output )
free((void *)shell_env->output);
free( ptr );
free( handle );
}
}
static void rtems_shell_create_file(const char *name, const char *content)
@@ -147,6 +177,70 @@ static void rtems_shell_init_once(void)
"running on %m\n");
rtems_shell_init_commands();
rtems_shell_register_monitor_commands();
}
void rtems_shell_init_environment(void)
{
assert(pthread_once(&rtems_shell_once, rtems_shell_init_once) == 0);
}
/*
* Set the shell env into the current thread's shell key.
*/
static bool rtems_shell_set_shell_env(
rtems_shell_env_t* shell_env
)
{
/*
* The shell environment can be managed or it can be provided by a
* user. We need to create a handle to hold the env pointer.
*/
rtems_shell_env_key_handle *handle;
int eno;
handle = malloc(sizeof(rtems_shell_env_key_handle));
if (handle == NULL) {
rtems_error(0, "no memory for shell env key handle)");
return false;
}
handle->managed = shell_env->managed;
handle->env = shell_env;
eno = pthread_setspecific(rtems_shell_current_env_key, handle);
if (eno != 0) {
rtems_error(0, "pthread_setspecific(shell_current_env_key): set");
return false;
}
return true;
}
/*
* Clear the current thread's shell key.
*/
static void rtems_shell_clear_shell_env(void)
{
int eno;
/*
* Run the destructor manually.
*/
rtems_shell_env_free(pthread_getspecific(rtems_shell_current_env_key));
/*
* Clear the key
*/
eno = pthread_setspecific(rtems_shell_current_env_key, NULL);
if (eno != 0)
rtems_error(0, "pthread_setspecific(shell_current_env_key): clear");
/*
* Clear stdin and stdout file pointers of they will be closed
*/
stdin = NULL;
stdout = NULL;
}
/*
@@ -154,7 +248,10 @@ static void rtems_shell_init_once(void)
*/
rtems_shell_env_t *rtems_shell_get_current_env(void)
{
return (rtems_shell_env_t *) pthread_getspecific(rtems_shell_current_env_key);
rtems_shell_env_key_handle *handle;
handle = (rtems_shell_env_key_handle*)
pthread_getspecific(rtems_shell_current_env_key);
return handle == NULL ? NULL : handle->env;
}
/*
@@ -164,15 +261,27 @@ rtems_shell_env_t *rtems_shell_get_current_env(void)
void rtems_shell_dup_current_env(rtems_shell_env_t *copy)
{
rtems_shell_env_t *env = rtems_shell_get_current_env();
if (env) {
if (env != NULL) {
shell_std_debug("dup: existing parent\n");
*copy = *env;
}
else {
memset(copy, 0, sizeof(rtems_shell_env_t));
copy->magic = rtems_build_name('S', 'E', 'N', 'V');
copy->devname = CONSOLE_DEVICE_NAME;
copy->taskname = "RTSH";
*copy = rtems_global_shell_env;
copy->magic = rtems_build_name('S', 'E', 'N', 'V');
copy->devname = CONSOLE_DEVICE_NAME;
copy->taskname = "RTSH";
copy->parent_stdout = stdout;
copy->parent_stdin = stdin;
copy->parent_stderr = stderr;
shell_std_debug("dup: global: copy: %p out: %d (%p) in: %d (%p)\n",
copy,
fileno(copy->parent_stdout), copy->parent_stdout,
fileno(copy->parent_stdin), copy->parent_stdin);
}
/*
* Duplicated environments are not managed.
*/
copy->managed = false;
}
/*
@@ -197,14 +306,21 @@ static int rtems_shell_line_editor(
int up;
int cmd = -1;
int inserting = 1;
int in_fileno = fileno(in);
int out_fileno = fileno(out);
output = (out && isatty(fileno(in)));
/*
* Only this task can use this file descriptor because calling
* fileno will block if another thread call made a call on this
* descriptor.
*/
output = (out && isatty(in_fileno));
col = last_col = 0;
tcdrain(fileno(in));
tcdrain(in_fileno);
if (out)
tcdrain(fileno(out));
tcdrain(out_fileno);
if (output && prompt)
fprintf(out, "\r%s", prompt);
@@ -540,9 +656,9 @@ static int rtems_shell_line_editor(
static bool rtems_shell_login(rtems_shell_env_t *env, FILE * in,FILE * out)
{
FILE *fd;
int c;
time_t t;
FILE *fd;
int c;
time_t t;
if (out) {
if ((env->devname[5]!='p')||
@@ -550,9 +666,9 @@ static bool rtems_shell_login(rtems_shell_env_t *env, FILE * in,FILE * out)
(env->devname[7]!='y')) {
fd = fopen("/etc/issue","r");
if (fd) {
while ((c=fgetc(fd))!=EOF) {
while ((c = fgetc(fd)) != EOF) {
if (c=='@') {
switch(c=fgetc(fd)) {
switch (c = fgetc(fd)) {
case 'L':
fprintf(out,"%s", env->devname);
break;
@@ -701,109 +817,115 @@ static bool rtems_shell_init_user_env(void)
#define RTEMS_SHELL_PROMPT_SIZE (128)
bool rtems_shell_main_loop(
rtems_shell_env_t *shell_env_arg
rtems_shell_env_t *shell_env
)
{
rtems_shell_env_t *shell_env;
int eno;
struct termios term;
struct termios previous_term;
char *prompt = NULL;
int cmd;
int cmd_count = 1; /* assume a script and so only 1 command line */
char *cmds[RTEMS_SHELL_CMD_COUNT];
char *cmd_argv;
int argc;
char *argv[RTEMS_SHELL_MAXIMUM_ARGUMENTS];
bool result = true;
bool input_file = false;
int line = 0;
FILE *stdinToClose = NULL;
FILE *stdoutToClose = NULL;
struct termios term;
struct termios previous_term;
char *prompt = NULL;
int cmd;
int cmd_count = 1; /* assume a script and so only 1 command line */
char *cmds[RTEMS_SHELL_CMD_COUNT];
char *cmd_argv;
int argc;
char *argv[RTEMS_SHELL_MAXIMUM_ARGUMENTS];
bool result = true;
bool input_file = false;
int line = 0;
FILE *stdinToClose = NULL;
FILE *stdoutToClose = NULL;
eno = pthread_once(&rtems_shell_once, rtems_shell_init_once);
assert(eno == 0);
rtems_shell_init_environment();
rtems_shell_register_monitor_commands();
shell_env = rtems_shell_init_env(shell_env_arg);
if (shell_env == NULL) {
rtems_error(0, "rtems_shell_init_env");
if (shell_env->magic != rtems_build_name('S', 'E', 'N', 'V')) {
rtems_error(0, "invalid shell environment passed to the main loop)");
return false;
}
eno = pthread_setspecific(rtems_shell_current_env_key, shell_env);
if (eno != 0) {
rtems_error(0, "pthread_setspecific(shell_current_env_key)");
if (!rtems_shell_set_shell_env(shell_env))
return false;
}
if (!rtems_shell_init_user_env()) {
rtems_error(0, "rtems_shell_init_user_env");
rtems_shell_clear_shell_env();
return false;
}
fileno(stdout);
shell_std_debug("env: %p\n", shell_env);
/* fprintf( stderr,
"-%s-%s-\n", shell_env->input, shell_env->output );
*/
if (shell_env->output && strcmp(shell_env->output, "stdout") != 0) {
if (strcmp(shell_env->output, "stderr") == 0) {
if (shell_env->output == NULL || strcmp(shell_env->output, "stdout") == 0) {
if (shell_env->parent_stdout != NULL)
stdout = shell_env->parent_stdout;
}
else if (strcmp(shell_env->output, "stderr") == 0) {
if (shell_env->parent_stderr != NULL)
stdout = shell_env->parent_stderr;
else
stdout = stderr;
} else if (strcmp(shell_env->output, "/dev/null") == 0) {
fclose (stdout);
} else {
FILE *output = fopen(shell_env_arg->output,
shell_env_arg->output_append ? "a" : "w");
if (!output) {
fprintf(stderr, "shell: open output %s failed: %s\n",
shell_env_arg->output, strerror(errno));
return false;
}
stdout = output;
stdoutToClose = output;
} else if (strcmp(shell_env->output, "/dev/null") == 0) {
fclose (stdout);
} else {
FILE *output = fopen(shell_env->output,
shell_env->output_append ? "a" : "w");
if (output == NULL) {
fprintf(stderr, "shell: open output %s failed: %s\n",
shell_env->output, strerror(errno));
rtems_shell_clear_shell_env();
return false;
}
stdout = output;
stdoutToClose = output;
}
if (shell_env->input && strcmp(shell_env_arg->input, "stdin") != 0) {
FILE *input = fopen(shell_env_arg->input, "r");
if (!input) {
if (shell_env->input == NULL || strcmp(shell_env->input, "stdin") == 0) {
if (shell_env->parent_stdin != NULL)
stdin = shell_env->parent_stdin;
} else {
FILE *input = fopen(shell_env->input, "r");
if (input == NULL) {
fprintf(stderr, "shell: open input %s failed: %s\n",
shell_env_arg->input, strerror(errno));
shell_env->input, strerror(errno));
if (stdoutToClose != NULL)
fclose(stdoutToClose);
rtems_shell_clear_shell_env();
return false;
}
stdin = input;
stdinToClose = input;
shell_env->forever = false;
input_file =true;
input_file = true;
}
else {
/* make a raw terminal,Linux Manuals */
if (!input_file) {
/* Make a raw terminal, Linux Manuals */
if (tcgetattr(fileno(stdin), &previous_term) >= 0) {
term = previous_term;
term.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
term.c_oflag &= ~OPOST;
term.c_oflag |= (OPOST|ONLCR); /* But with cr+nl on output */
term.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
term.c_cflag |= CLOCAL | CREAD;
term.c_cflag |= CLOCAL | CREAD;
term.c_cc[VMIN] = 1;
term.c_cc[VTIME] = 0;
if (tcsetattr (fileno(stdin), TCSADRAIN, &term) < 0) {
fprintf(stderr,
"shell:cannot set terminal attributes(%s)\n",shell_env->devname);
"shell: cannot set terminal attributes(%s)\n",shell_env->devname);
}
}
cmd_count = RTEMS_SHELL_CMD_COUNT;
prompt = malloc(RTEMS_SHELL_PROMPT_SIZE);
if (!prompt)
fprintf(stderr,
"shell:cannot allocate prompt memory\n");
"shell: cannot allocate prompt memory\n");
}
setvbuf(stdin,NULL,_IONBF,0); /* Not buffered*/
setvbuf(stdout,NULL,_IONBF,0); /* Not buffered*/
shell_std_debug("child out: %d (%p)\n", fileno(stdout), stdout);
shell_std_debug("child in: %d (%p)\n", fileno(stdin), stdin);
/* Do not buffer if interactive else leave buffered */
if (!input_file)
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
/*
* Allocate the command line buffers.
@@ -866,8 +988,6 @@ bool rtems_shell_main_loop(
shell_env->exit_shell = false;
for (;;) {
int cmd;
/* Prompt section */
if (prompt) {
rtems_shell_get_prompt(shell_env, prompt,
@@ -882,8 +1002,10 @@ bool rtems_shell_main_loop(
if (cmd == -1)
continue; /* empty line */
if (cmd == -2)
if (cmd == -2) {
result = false;
break; /*EOF*/
}
line++;
@@ -921,7 +1043,11 @@ bool rtems_shell_main_loop(
memcpy (cmd_argv, cmds[cmd], RTEMS_SHELL_CMD_SIZE);
if (!rtems_shell_make_args(cmd_argv, &argc, argv,
RTEMS_SHELL_MAXIMUM_ARGUMENTS)) {
shell_env->errorlevel = rtems_shell_execute_cmd(argv[0], argc, argv);
int exit_code = rtems_shell_execute_cmd(argv[0], argc, argv);
if (shell_env->exit_code != NULL)
*shell_env->exit_code = exit_code;
if (exit_code != 0 && shell_env->exit_on_error)
shell_env->exit_shell = true;
}
/* end exec cmd section */
@@ -932,6 +1058,7 @@ bool rtems_shell_main_loop(
fflush( stdout );
fflush( stderr );
}
shell_std_debug("end: %d %d\n", result, shell_env->forever);
} while (result && shell_env->forever);
}
@@ -943,6 +1070,9 @@ bool rtems_shell_main_loop(
if (prompt)
free (prompt);
shell_std_debug("child in-to-close: %p\n", stdinToClose);
shell_std_debug("child out-to-close: %p\n", stdoutToClose);
if (stdinToClose) {
fclose( stdinToClose );
} else {
@@ -956,6 +1086,7 @@ bool rtems_shell_main_loop(
}
if ( stdoutToClose )
fclose( stdoutToClose );
rtems_shell_clear_shell_env();
return result;
}
@@ -971,6 +1102,7 @@ static rtems_status_code rtems_shell_run (
const char *output,
bool output_append,
rtems_id wake_on_end,
int *exit_code,
bool echo,
rtems_shell_login_check_t login_check
)
@@ -980,6 +1112,8 @@ static rtems_status_code rtems_shell_run (
rtems_shell_env_t *shell_env;
rtems_name name;
rtems_shell_init_environment();
if ( task_name && strlen(task_name) >= 4)
name = rtems_build_name(
task_name[0], task_name[1], task_name[2], task_name[3]);
@@ -1005,25 +1139,41 @@ static rtems_status_code rtems_shell_run (
"allocating shell_env %s in shell_init()",task_name);
return RTEMS_NO_MEMORY;
}
shell_std_debug("run: env: %p\n", shell_env);
shell_env->devname = devname;
shell_env->taskname = task_name;
shell_env->exit_shell = false;
shell_env->forever = forever;
shell_env->echo = echo;
shell_env->input = strdup (input);
shell_env->output = strdup (output);
shell_env->input = input == NULL ? NULL : strdup (input);
shell_env->output = output == NULL ? NULL : strdup (output);
shell_env->output_append = output_append;
shell_env->parent_stdin = stdin;
shell_env->parent_stdout = stdout;
shell_env->parent_stderr = stderr;
shell_env->wake_on_end = wake_on_end;
shell_env->exit_code = exit_code;
shell_env->login_check = login_check;
shell_env->uid = getuid();
shell_env->gid = getgid();
getcwd(shell_env->cwd, sizeof(shell_env->cwd));
shell_std_debug("run out: %d (%p)\n",
fileno(shell_env->parent_stdout), shell_env->parent_stdout);
shell_std_debug("run in: %d (%p)\n",
fileno(shell_env->parent_stdin), shell_env->parent_stdin);
sc = rtems_task_start(task_id, rtems_shell_task,
(rtems_task_argument) shell_env);
(rtems_task_argument) shell_env);
if (sc != RTEMS_SUCCESSFUL) {
rtems_error(sc,"starting task %s in shell_init()",task_name);
free( (void*) shell_env->input );
free( (void*) shell_env->output );
free( shell_env );
return sc;
}
@@ -1032,7 +1182,9 @@ static rtems_status_code rtems_shell_run (
sc = rtems_event_receive (RTEMS_EVENT_1, RTEMS_WAIT, 0, &out);
}
return 0;
shell_std_debug("run: end: sc:%d ec:%d\n", sc, *exit_code);
return sc;
}
rtems_status_code rtems_shell_init(
@@ -1046,6 +1198,7 @@ rtems_status_code rtems_shell_init(
)
{
rtems_id to_wake = RTEMS_ID_NONE;
int exit_code = 0;
if ( wait )
to_wake = rtems_task_self();
@@ -1061,12 +1214,13 @@ rtems_status_code rtems_shell_init(
"stdout", /* output */
false, /* output_append */
to_wake, /* wake_on_end */
&exit_code, /* exit code of command */
false, /* echo */
login_check /* login check */
);
}
rtems_status_code rtems_shell_script (
rtems_status_code rtems_shell_script (
const char *task_name,
size_t task_stacksize,
rtems_task_priority task_priority,
@@ -1077,14 +1231,14 @@ rtems_status_code rtems_shell_script (
bool echo
)
{
rtems_id current_task = RTEMS_INVALID_ID;
rtems_id to_wake = RTEMS_ID_NONE;
int exit_code = 0;
rtems_status_code sc;
if (wait) {
sc = rtems_task_ident (RTEMS_SELF, RTEMS_LOCAL, &current_task);
if (sc != RTEMS_SUCCESSFUL)
return sc;
}
shell_std_debug("script: in: %s out: %s\n", input, output);
if ( wait )
to_wake = rtems_task_self();
sc = rtems_shell_run(
task_name, /* task_name */
@@ -1096,12 +1250,19 @@ rtems_status_code rtems_shell_script (
input, /* input */
output, /* output */
output_append, /* output_append */
current_task, /* wake_on_end */
to_wake, /* wake_on_end */
&exit_code, /* exit_code */
echo, /* echo */
NULL /* login check */
);
if (sc != RTEMS_SUCCESSFUL)
return sc;
if (sc == RTEMS_SUCCESSFUL)
{
/* Place holder until RTEMS 5 is released then the interface for
* this call will change. */
}
shell_std_debug("script: end: %d\n", sc);
return sc;
}

View File

@@ -94,6 +94,14 @@ typedef struct {
const char *alias;
} rtems_shell_alias_t;
struct rtems_shell_topic_tt;
typedef struct rtems_shell_topic_tt rtems_shell_topic_t;
struct rtems_shell_topic_tt {
const char *topic;
rtems_shell_topic_t *next;
};
/*
* The return value has RTEMS_SHELL_KEYS_EXTENDED set if the key
* is extended, ie a special key.
@@ -125,6 +133,26 @@ extern int rtems_shell_make_args(
int max_args
);
extern rtems_shell_topic_t * rtems_shell_lookup_topic(
const char *topic
);
extern bool rtems_shell_can_see_cmd(
const rtems_shell_cmd_t *shell_cmd
);
extern int rtems_shell_execute_cmd(
const char *cmd, int argc, char *argv[]
);
/*
* Call to set up the shell environment if you need to execute commands before
* running a shell.
*/
extern void rtems_shell_init_environment(
void
);
extern int rtems_shell_cat_file(
FILE *out,
const char *name
@@ -189,19 +217,24 @@ extern rtems_status_code rtems_shell_script(
/**
* Private environment associated with each shell instance.
*/
typedef struct {
typedef struct rtems_shell_env {
/** 'S','E','N','V': Shell Environment */
rtems_name magic;
bool managed;
const char *devname;
const char *taskname;
bool exit_shell; /* logout */
bool forever; /* repeat login */
int errorlevel;
int *exit_code;
bool exit_on_error;
bool echo;
char cwd[256];
const char *input;
const char *output;
bool output_append;
FILE *parent_stdin;
FILE *parent_stdout;
FILE *parent_stderr;
rtems_id wake_on_end;
rtems_shell_login_check_t login_check;

View File

@@ -2989,10 +2989,16 @@ static void gmt_time_string(char *buf, size_t buf_len, time_t *t) {
strftime(buf, buf_len, "%a, %d %b %Y %H:%M:%S GMT", gmtime(t));
}
static void construct_etag(char *buf, size_t buf_len,
static void construct_etag(const struct mg_connection *conn, const char *path,
char *buf, size_t buf_len,
const struct file *filep) {
snprintf(buf, buf_len, "\"%lx.%" INT64_FMT "\"",
(unsigned long) filep->modification_time, filep->size);
if (conn->ctx->callbacks.http_etag != NULL &&
conn->ctx->callbacks.http_etag(conn, path, buf, buf_len)) {
}
else {
snprintf(buf, buf_len, "\"%lx.%" INT64_FMT "\"",
(unsigned long) filep->modification_time, filep->size);
}
}
static void fclose_on_exec(struct file *filep) {
@@ -3061,7 +3067,7 @@ static void handle_file_request(struct mg_connection *conn, const char *path,
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3
gmt_time_string(date, sizeof(date), &curtime);
gmt_time_string(lm, sizeof(lm), &filep->modification_time);
construct_etag(etag, sizeof(etag), filep);
construct_etag(conn, path, etag, sizeof(etag), filep);
(void) mg_printf(conn,
"HTTP/1.1 %d %s\r\n"
@@ -3221,11 +3227,12 @@ static int substitute_index_file(struct mg_connection *conn, char *path,
// Return True if we should reply 304 Not Modified.
static int is_not_modified(const struct mg_connection *conn,
const char *path,
const struct file *filep) {
char etag[64];
const char *ims = mg_get_header(conn, "If-Modified-Since");
const char *inm = mg_get_header(conn, "If-None-Match");
construct_etag(etag, sizeof(etag), filep);
construct_etag(conn, path, etag, sizeof(etag), filep);
return (inm != NULL && !mg_strcasecmp(etag, inm)) ||
(ims != NULL && filep->modification_time <= parse_date_string(ims));
}
@@ -4591,7 +4598,7 @@ static void handle_request(struct mg_connection *conn) {
strlen(conn->ctx->config[SSI_EXTENSIONS]),
path) > 0) {
handle_ssi_file_request(conn, path);
} else if (is_not_modified(conn, &file)) {
} else if (is_not_modified(conn, path, &file)) {
send_http_error(conn, 304, "Not Modified", "%s", "");
} else {
handle_file_request(conn, path, &file);

View File

@@ -124,6 +124,19 @@ struct mg_callbacks {
// Parameters:
// status: HTTP error status code.
int (*http_error)(struct mg_connection *, int status);
// Called when mongoose needs to generate an HTTP etag.
// Implementing this callback allows a custom etag to be generated. If
// not implemented the standard etag generator is used which is the
// modification time as a hex value and the file size.
// Use this callback if the modification time cannot be controlled.
// Parameters:
// path: path to the file being requested
// etag: buffer to write the etag into
// etag_len: the length of the etag buffer
// Return value:
int (*http_etag)(const struct mg_connection *,
const char *path, char *etag, size_t etag_len);
};
// Start web server.

View File

@@ -58,7 +58,7 @@ int aio_cancel(int fildes, struct aiocb *aiocbp)
rtems_chain_extract (&r_chain->next_fd);
rtems_aio_remove_fd (r_chain);
pthread_mutex_destroy (&r_chain->mutex);
pthread_cond_destroy (&r_chain->mutex);
pthread_cond_destroy (&r_chain->cond);
free (r_chain);
pthread_mutex_unlock (&aio_request_queue.mutex);

View File

@@ -212,6 +212,10 @@ $(PROJECT_INCLUDE)/rtems/rtl/rtl-sym.h: libdl/rtl-sym.h $(PROJECT_INCLUDE)/rtems
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtl/rtl-sym.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtl/rtl-sym.h
$(PROJECT_INCLUDE)/rtems/rtl/rtl-trace.h: libdl/rtl-trace.h $(PROJECT_INCLUDE)/rtems/rtl/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtl/rtl-trace.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtl/rtl-trace.h
$(PROJECT_INCLUDE)/rtems/rtl/rap.h: libdl/rap.h $(PROJECT_INCLUDE)/rtems/rtl/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtl/rap.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtl/rap.h

View File

@@ -2480,7 +2480,8 @@ const rtems_libio_helper rtems_fs_init_helper =
#define CONFIGURE_MEMORY_FOR_POSIX_KEYS(_keys, _key_value_pairs) \
(_Configure_Object_RAM(_keys, sizeof(POSIX_Keys_Control) ) \
+ _Configure_From_workspace( \
_key_value_pairs * sizeof(POSIX_Keys_Key_value_pair)))
_Configure_Max_Objects(_key_value_pairs) \
* sizeof(POSIX_Keys_Key_value_pair)))
/*
* The rest of the POSIX threads API features are only available when

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved.
* Copyright (c) 2013, 2017 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
@@ -44,9 +44,14 @@
#define FRAME_SIZE (FRAME_OFFSET_LR + 4)
#endif
.syntax unified
.section .text
#ifdef __thumb2__
FUNCTION_THUMB_ENTRY(_CPU_Context_validate)
#else
FUNCTION_ENTRY(_CPU_Context_validate)
#endif
/* Save */
@@ -99,12 +104,7 @@ FUNCTION_THUMB_ENTRY(_CPU_Context_validate)
#ifdef ARM_MULTILIB_VFP
/* R3 contains the FPSCR */
vmrs r3, FPSCR
movs r4, #0x001f
#ifdef ARM_MULTILIB_ARCH_V7M
movt r4, #0xf000
#else
movt r4, #0xf800
#endif
ldr r4, =0xf000001f
bic r3, r3, r4
and r4, r4, r0
orr r3, r3, r4
@@ -175,11 +175,34 @@ check:
bne restore
.endm
cmp r2, sp
/* A compare involving the stack pointer is deprecated */
mov r1, sp
cmp r2, r1
bne restore
mov r1, r0
#ifdef __thumb2__
cmp r1, r1
itttt eq
addeq r1, #1
addeq r1, #2
addeq r1, #4
addeq r1, #8
subs r1, #15
cmp r1, r0
bne restore
cmp r1, r1
iteee eq
addeq r1, #1
addne r1, #2
addne r1, #4
addne r1, #8
subs r1, #1
cmp r1, r0
bne restore
#endif
#ifndef ARM_MULTILIB_VFP
check_register r3
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved.
* Copyright (c) 2013, 2017 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
@@ -29,8 +29,7 @@ FUNCTION_THUMB_ENTRY(_CPU_Context_volatile_clobber)
#ifdef ARM_MULTILIB_VFP
vmrs r1, FPSCR
movs r2, #0x001f
movt r2, #0xf800
ldr r2, =0xf000001f
bic r1, r1, r2
and r2, r2, r0
orr r1, r1, r2

View File

@@ -28,10 +28,10 @@ void __attribute__((naked)) _ARMV7M_Exception_default( void )
"mov r2, lr\n"
"mrs r1, msp\n"
"mrs r0, psp\n"
"cmn r2, #3\n"
"itt ne\n"
"movne r0, r1\n"
"addne r0, %[cpufsz]\n"
"tst lr, #4\n"
"itt eq\n"
"moveq r0, r1\n"
"addeq r0, %[cpufsz]\n"
"add r2, r0, %[v7mlroff]\n"
"add r1, sp, %[cpulroff]\n"
"ldm r2, {r3-r5}\n"

View File

@@ -5,10 +5,10 @@
*/
/*
* Copyright (c) 2011-2014 Sebastian Huber. All rights reserved.
* Copyright (c) 2011, 2017 Sebastian Huber. All rights reserved.
*
* embedded brains GmbH
* Obere Lagerstr. 30
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
@@ -48,29 +48,42 @@ static void _ARMV7M_Trigger_lazy_floating_point_context_save( void )
void _ARMV7M_Pendable_service_call( void )
{
ARMV7M_Exception_frame *ef;
_ISR_Nest_level = 1;
_ARMV7M_SCB->icsr = ARMV7M_SCB_ICSR_PENDSVCLR;
_ARMV7M_Trigger_lazy_floating_point_context_save();
ef = (ARMV7M_Exception_frame *) _ARMV7M_Get_PSP();
--ef;
_ARMV7M_Set_PSP( (uint32_t) ef );
Per_CPU_Control *cpu_self = _Per_CPU_Get();
/*
* According to "ARMv7-M Architecture Reference Manual" section B1.5.6
* "Exception entry behavior" the return address is half-word aligned.
* We must check here if a thread dispatch is allowed. Right after a
* "msr basepri_max, %[basepri]" instruction an interrupt service may still
* take place. However, pendable service calls that are activated during
* this interrupt service may be delayed until interrupts are enable again.
*/
ef->register_pc = (void *)
((uintptr_t) _ARMV7M_Thread_dispatch & ~((uintptr_t) 1));
if (
( cpu_self->isr_nest_level | cpu_self->thread_dispatch_disable_level ) == 0
) {
ARMV7M_Exception_frame *ef;
ef->register_xpsr = 0x01000000U;
cpu_self->isr_nest_level = 1;
_ARMV7M_SCB->icsr = ARMV7M_SCB_ICSR_PENDSVCLR;
_ARMV7M_Trigger_lazy_floating_point_context_save();
ef = (ARMV7M_Exception_frame *) _ARMV7M_Get_PSP();
--ef;
_ARMV7M_Set_PSP( (uint32_t) ef );
/*
* According to "ARMv7-M Architecture Reference Manual" section B1.5.6
* "Exception entry behavior" the return address is half-word aligned.
*/
ef->register_pc = (void *)
((uintptr_t) _ARMV7M_Thread_dispatch & ~((uintptr_t) 1));
ef->register_xpsr = 0x01000000U;
}
}
void _ARMV7M_Supervisor_call( void )
{
Per_CPU_Control *cpu_self = _Per_CPU_Get();
ARMV7M_Exception_frame *ef;
_ARMV7M_Trigger_lazy_floating_point_context_save();
@@ -79,10 +92,9 @@ void _ARMV7M_Supervisor_call( void )
++ef;
_ARMV7M_Set_PSP( (uint32_t) ef );
_ISR_Nest_level = 0;
RTEMS_COMPILER_MEMORY_BARRIER();
cpu_self->isr_nest_level = 0;
if ( _Thread_Dispatch_necessary ) {
if ( cpu_self->dispatch_necessary ) {
_ARMV7M_Pendable_service_call();
}
}

View File

@@ -5,10 +5,10 @@
*/
/*
* Copyright (c) 2011 Sebastian Huber. All rights reserved.
* Copyright (c) 2011, 2017 Sebastian Huber. All rights reserved.
*
* embedded brains GmbH
* Obere Lagerstr. 30
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
@@ -30,19 +30,25 @@
void _ARMV7M_Interrupt_service_enter( void )
{
++_Thread_Dispatch_disable_level;
++_ISR_Nest_level;
Per_CPU_Control *cpu_self = _Per_CPU_Get();
++cpu_self->thread_dispatch_disable_level;
++cpu_self->isr_nest_level;
}
void _ARMV7M_Interrupt_service_leave( void )
{
--_ISR_Nest_level;
--_Thread_Dispatch_disable_level;
if (
_ISR_Nest_level == 0
&& _Thread_Dispatch_disable_level == 0
&& _Thread_Dispatch_necessary
) {
Per_CPU_Control *cpu_self = _Per_CPU_Get();
--cpu_self->thread_dispatch_disable_level;
--cpu_self->isr_nest_level;
/*
* Optimistically activate a pendable service call if a thread dispatch is
* necessary. The _ARMV7M_Pendable_service_call() will check that a thread
* dispatch is allowed.
*/
if ( cpu_self->dispatch_necessary ) {
_ARMV7M_SCB->icsr = ARMV7M_SCB_ICSR_PENDSVSET;
}
}

View File

@@ -314,9 +314,8 @@ RTEMS_INLINE_ROUTINE void _Thread_Dispatch_enable( Per_CPU_Control *cpu_self )
} else {
cpu_self->thread_dispatch_disable_level = 0;
_Profiling_Thread_dispatch_enable( cpu_self, 0 );
_ISR_Enable_without_giant( level );
}
_ISR_Enable_without_giant( level );
} else {
cpu_self->thread_dispatch_disable_level = disable_level - 1;
}

View File

@@ -1,36 +0,0 @@
ACLOCAL_AMFLAGS = -I ../aclocal
# NOTE: The order of the directories is essential.
# + tools, common and images are shared across many documents
SUBDIRS = tools started user bsp_howto porting develenv posix_users \
posix1003.1 filesystem networking ada_user \
new_chapters relnotes cpu_supplement shell
if USE_HTML
html_DATA = index.html
endif
EXTRA_DIST = common/cpright.texi common/setup.texi \
common/treedef.tex common/rtems.texi.in
if USE_HTML
html_imagesdir = $(htmldir)/images
endif
HTML_IMAGES = images/dir-arrow.gif images/dvi.gif images/missing-arrow.gif \
images/next-arrow.gif images/oaronly.jpg images/pdf.gif images/pdf1.gif \
images/rtems_logo.jpg images/prev-arrow.gif images/ps.gif \
images/up-arrow.gif
if USE_HTML
html_images_DATA = $(HTML_IMAGES)
endif
EXTRA_DIST += $(HTML_IMAGES)
CLEANFILES = common/rtems.texi
DISTCLEANFILES = common/rtems.sed
# HACK: This should not be here, but it makes "make distcheck" work.
EXTRA_DIST += ../scripts/setup.def ../COPYING

View File

@@ -1,48 +0,0 @@
Tools Required
==============
The following tools are used in the production of this documentation:
TeX
texi2html 1.82
texinfo-tex 4.13a
texi2html will be deprecated in the upcomine texinfo release. At that point,
we will need to provide support for texi2any.pl as an alternative means to
produce html output.
This was used by the authors to generate the directory tree figure
in the texinfo printed version:
tree (from the CTAN Archives -- see http://jasper.ora.com/ctan.html)
Changing the Version Number and Timestamp
=========================================
RTEMS Version number is in configure.in. Edit that file and run bootstrap.
Documentation date is in common/setup.texi.in and also must be modified
by hand. bootstrap does not have to be run after modifying this file.
Making the Documentation
========================
cd rtems-XXX/doc
../bootstrap
./configure --enable-maintainer-mode
make all
make install
Cleaning
========
make clean
make distclean
make maintainer-clean
Making a Source Distribution
============================
This generates a rtems-<version>.tar.gz in the toplevel directory.
Making a Preformatted Distribution
==================================
Install and tar it up. :)

View File

@@ -1,91 +0,0 @@
This is a collection of things which need to be done to the various
manuals.
General Issues
==============
May need a Documentation Roadmap - for now, the "Where to
go from here" chapter in Getting Started is it.
Need a description of hello world and writing an application.
More automatic handling of version, date, revision, release, etc.
Eliminate use of gifs. [NOTE: ps, pdf, and dvi.gif are from
http://www.cit.gu.edu.au/images and the various arrow and
bookshelf icons came with texi2www.]
Redraw pictures as appropriate in open source tools.
Getting Started (C and Ada versions)
====================================
Switch back to using @url{} when pdf generation error is fixed.
Classic Users Guide
===================
May need to enhance descriptions in Primitive Data Types Chapter
POSIX User Notes
================
Add pages for network services.
Add timer() services if we have any.
Development Environment Guide
=============================
Either rename to "A Tour of the RTEMS Source Tree" or include
more information on the GNU tools.
The "C Suites" section is oddly named and the directory
tree included is wrong in that make is no longer under
the c directory. I think the build-tools make have
moved as well.
All the paths should be provided as relative paths
from the top of the RTEMS source tree. It wastes
valuable screen space to do otherwise.
The last paragraph of "C Suites" is vague and could
be written better. It should include the subdirectory
names as part of the textual description.
Should this documentation even use the phrase "C Implementation"
any longer?
Directory names should be in @code -- not "quoted".
In "Support Library Source Directory", look for "which installed"
In the latter part of the "libbsp" paragraph in "Support
Library Source Directory", there is reference to the
stubdr directory which is no longer there.
Update this section to include discussion of the shared
subdirectory and its relationship to the BSPs. Write this
in such a way that it can be passed on to Geoffroy Montel.
In the section, "Test Suite Source Directory", there is a
numeric count of the number of tests in each suite. This
should be eliminated for maintenance purposes.
The psxtest directory is not mentioned. Check that no others
have been forgotten.
There should probably be no reference to the Ada sample
applications. This document used to cover both implementations.
This now seems inappropriate.
The hello world sample test discussion mentions that it provides
a rudiementary test of the BSP startup code and the "RTEMS
C Library". This should be rewritten to tell mroe about what
this test shows (actually a lot). It should mention that this
test tries to avoid using interrupts.
The ticker test should mention that in contrast to hello, it
does use interrupts. :) It can be used to tune the clock
tick.
The ticker test documentation says it calls "tm_get" -- jeez
how old is this manual.

View File

@@ -1,18 +0,0 @@
## _RTEMS_UPDATE_CONDITIONAL(FINAL,TMP)
AC_DEFUN([_RTEMS_UPDATE_CONDITIONAL],[
AS_IF([test -f $1],[
AS_IF([cmp -s $1 $2 2>/dev/null],
[
AC_MSG_NOTICE([$1 is unchanged])
rm -f $$2
],[
AC_MSG_NOTICE([creating $1])
rm -f $1
mv $2 $1
])
],[
AC_MSG_NOTICE([creating $1])
rm -f $1
mv $2 $1
])
])

View File

@@ -1,72 +0,0 @@
#
# COPYRIGHT (c) 1988-2002.
# On-Line Applications Research Corporation (OAR).
# All rights reserved.
PROJECT = ada_user
include $(top_srcdir)/project.am
include $(top_srcdir)/main.am
COMMON_FILES += \
$(top_builddir)/user/barrier.texi $(top_builddir)/user/bsp.texi \
$(top_builddir)/user/clock.texi $(top_builddir)/user/concepts.texi \
$(top_builddir)/user/datatypes.texi $(top_builddir)/user/conf.texi \
$(top_builddir)/user/dirstat.texi $(top_builddir)/user/dpmem.texi \
$(top_builddir)/user/event.texi $(top_builddir)/user/fatal.texi \
$(top_builddir)/user/glossary.texi $(top_builddir)/user/init.texi \
$(top_builddir)/user/intr.texi $(top_builddir)/user/io.texi \
$(top_builddir)/user/libpci.texi \
$(top_builddir)/user/mp.texi $(top_builddir)/user/msg.texi \
$(top_builddir)/user/overview.texi $(top_builddir)/user/part.texi \
$(top_builddir)/user/preface.texi $(top_builddir)/user/region.texi \
$(top_builddir)/user/rtmon.texi $(top_builddir)/user/schedule.texi \
$(top_builddir)/user/sem.texi $(top_builddir)/user/signal.texi \
$(top_builddir)/user/task.texi $(top_builddir)/user/timer.texi \
$(top_builddir)/user/userext.texi $(top_builddir)/user/stackchk.texi \
$(top_builddir)/user/cpuuse.texi $(top_srcdir)/common/cpright.texi \
$(top_builddir)/user/object.texi $(top_builddir)/user/cbs.texi \
$(top_builddir)/user/smp.texi
FILES = example.texi
ObjectId-16Bits.eps: $(top_srcdir)/user/ObjectId-16Bits.eps
$(LN_S) $<
ObjectId-32Bits.eps: $(top_srcdir)/user/ObjectId-32Bits.eps
$(LN_S) $<
rtemspie.eps: $(top_srcdir)/user/rtemspie.eps
$(LN_S) $<
semaphore_attributes.eps: $(top_srcdir)/user/semaphore_attributes.eps
$(LN_S) $<
states.eps: $(top_srcdir)/user/states.eps
$(LN_S) $<
CLEANFILES += ObjectId-16Bits.eps ObjectId-32Bits.eps rtemspie.eps semaphore_attributes.eps states.eps
ObjectId-16Bits.png: $(top_srcdir)/user/ObjectId-16Bits.png
$(LN_S) $<
ObjectId-32Bits.png: $(top_srcdir)/user/ObjectId-32Bits.png
$(LN_S) $<
rtemsarc.png: $(top_srcdir)/user/rtemsarc.png
$(LN_S) $<
rtemspie.png: $(top_srcdir)/user/rtemspie.png
$(LN_S) $<
semaphore_attributes.png: $(top_srcdir)/user/semaphore_attributes.png
$(LN_S) $<
states.png: $(top_srcdir)/user/states.png
$(LN_S) $<
CLEANFILES += ObjectId-16Bits.png ObjectId-32Bits.png rtemsarc.png rtemspie.png semaphore_attributes.png states.png
info_TEXINFOS = ada_user.texi
ada_user_TEXINFOS = $(FILES) $(COMMON_FILES)
if USE_HTML
html_project_DATA += rtemsarc.png rtemspie.png states.png \
ObjectId-16Bits.png ObjectId-32Bits.png semaphore_attributes.png
endif
$(PROJECT).dvi: rtemspie.eps states.eps ObjectId-16Bits.eps \
ObjectId-32Bits.eps semaphore_attributes.eps
PDF_IMAGES = rtemspie.pdf states.pdf ObjectId-16Bits.pdf \
ObjectId-32Bits.pdf semaphore_attributes.pdf
CLEANFILES += ada_user.info ada_user.info-? ada_user.info-??

View File

@@ -1,183 +0,0 @@
\input texinfo @c -*-texinfo-*-
@c %**start of header
@setfilename ada_user.info
@setcontentsaftertitlepage
@syncodeindex vr fn
@synindex ky cp
@paragraphindent 0
@c %**end of header
@c
@c COPYRIGHT (c) 1989-2014.
@c On-Line Applications Research Corporation (OAR).
@c All rights reserved.
@c
@c Master file for the Ada User's Guide
@c
@c Joel's Questions
@c
@c 1. Why does paragraphindent only impact makeinfo?
@c 2. Why does paragraphindent show up in HTML?
@c
@include version.texi
@include common/setup.texi
@include common/rtems.texi
@ifset use-ascii
@dircategory RTEMS On-Line Manual
@direntry
* RTEMS Ada User: (ada_user). The Ada User's Guide
@end direntry
@end ifset
@c variable substitution info:
@c
@clear is-C
@set is-Ada
@set LANGUAGE Ada
@set STRUCTURE record
@set ROUTINE subprogram
@set OR or
@set RPREFIX RTEMS.
@set DIRPREFIX rtems.
@c the language is @value{LANGUAGE}
@c NOTE: don't use underscore in the name
@c
@c
@c Title Page Stuff
@c
@c
@c I don't really like having a short title page. --joel
@c
@c @shorttitlepage RTEMS Applications Ada User's Guide
@setchapternewpage odd
@settitle RTEMS Ada User's Guide
@titlepage
@finalout
@title RTEMS Applications Ada User's Guide
@subtitle Edition @value{EDITION}, for RTEMS @value{VERSION}
@sp 1
@subtitle @value{UPDATED}
@author On-Line Applications Research Corporation
@page
@include common/cpright.texi
@end titlepage
@c This prevents a black box from being printed on "overflow" lines.
@c The alternative is to rework a sentence to avoid this problem.
@contents
@ifnottex
@node Top, List of Figures, (dir), (dir)
@top RTEMS Applications Ada User's Guide
@menu
* List of Figures::
* Preface::
* Overview::
* Key Concepts::
* RTEMS Data Types::
* Initialization Manager::
* Task Manager::
* Interrupt Manager::
* Clock Manager::
* Timer Manager::
* Semaphore Manager::
* Message Manager::
* Event Manager::
* Signal Manager::
* Partition Manager::
* Region Manager::
* Dual-Ported Memory Manager::
* I/O Manager::
* Fatal Error Manager::
* Scheduling Concepts::
* Rate Monotonic Manager::
* Barrier Manager::
* Board Support Packages::
* User Extensions Manager::
* Configuring a System::
* Multiprocessing Manager::
* Symmetric Multiprocessing Services::
* PCI Library::
* Stack Bounds Checker::
* CPU Usage Statistics::
* Object Services::
* Chains::
* Red-Black Trees::
* Timespec Helpers::
* Constant Bandwidth Server Scheduler API::
* Directive Status Codes::
* Example Application::
* Glossary::
* Command and Variable Index::
* Concept Index::
@end menu
@end ifnottex
@node List of Figures, Preface, Top, Top
@unnumbered List of Figures
@listoffloats Figure
@include user/preface.texi
@include user/overview.texi
@include user/concepts.texi
@include user/datatypes.texi
@include user/init.texi
@include user/task.texi
@include user/intr.texi
@include user/clock.texi
@include user/timer.texi
@include user/sem.texi
@include user/msg.texi
@include user/event.texi
@include user/signal.texi
@include user/part.texi
@include user/region.texi
@include user/dpmem.texi
@include user/io.texi
@include user/fatal.texi
@include user/schedule.texi
@include user/rtmon.texi
@include user/barrier.texi
@include user/bsp.texi
@include user/userext.texi
@include user/conf.texi
@include user/mp.texi
@include user/smp.texi
@include user/libpci.texi
@include user/stackchk.texi
@include user/cpuuse.texi
@include user/object.texi
@include user/chains.texi
@include user/rbtree.texi
@include user/timespec.texi
@include user/cbs.texi
@include user/dirstat.texi
@include example.texi
@include user/glossary.texi
@node Command and Variable Index, Concept Index, Glossary, Top
@unnumbered Command and Variable Index
@c There are currently no Command and Variable Index entries.
@printindex fn
@node Concept Index, , Command and Variable Index, Top
@unnumbered Concept Index
@c There are currently no Concept Index entries.
@printindex cp
@bye

View File

@@ -1,13 +0,0 @@
@c
@c COPYRIGHT (c) 1989-2014.
@c On-Line Applications Research Corporation (OAR).
@c All rights reserved.
@node Example Application, Glossary, Directive Status Codes STATUS_TEXT - Returns the enumeration name for a status code, Top
@chapter Example Application
@example
Currently there is no example Ada application provided.
@end example

View File

@@ -1,4 +0,0 @@
@set UPDATED 24 February 2013
@set UPDATED-MONTH February 2013
@set EDITION 4.10.99.0
@set VERSION 4.10.99.0

View File

@@ -1,4 +0,0 @@
@set UPDATED 17 July 2015
@set UPDATED-MONTH July 2015
@set EDITION 4.10.99.0
@set VERSION 4.10.99.0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

View File

@@ -1,135 +0,0 @@
#
# COPYRIGHT (c) 1988-2002.
# On-Line Applications Research Corporation (OAR).
# All rights reserved.
PROJECT = bsp_howto
include $(top_srcdir)/project.am
include $(top_srcdir)/main.am
GENERATED_FILES = intro.texi target.texi makefiles.texi linkcmds.texi \
support.texi adaintr.texi init.texi console.texi clock.texi timer.texi \
rtc.texi ata.texi ide-ctrl.texi nvmem.texi network.texi shmsupp.texi \
framebuffer.texi analog.texi discrete.texi
COMMON_FILES += $(top_srcdir)/common/cpright.texi
PNG_FILES = Developer-User-Timeline.png BSPInitFlowchart-49.png \
TERMIOSFlow.png
if USE_HTML
html_project_DATA += $(PNG_FILES)
endif
FILES =
info_TEXINFOS = bsp_howto.texi
bsp_howto_TEXINFOS = $(FILES) $(COMMON_FILES) $(GENERATED_FILES)
#
# Process Automatically Generated Files
#
intro.texi: intro.t
$(BMENU2) -p "Top" \
-u "Top" \
-n "Target Dependent Files" < $< > $@
target.texi: target.t
$(BMENU2) -p "Introduction" \
-u "Top" \
-n "Makefiles" < $< > $@
makefiles.texi: makefiles.t
$(BMENU2) -p "Target Dependent Files Board Support Package Structure" \
-u "Top" \
-n "Linker Script" < $< > $@
linkcmds.texi: linkcmds.t
$(BMENU2) -p "Makefiles Creating a New BSP Make Customization File" \
-u "Top" \
-n "Ada95 Interrupt Support" < $< > $@
adaintr.texi: adaintr.t
$(BMENU2) -p "Linker Script Initialized Data" \
-u "Top" \
-n "Miscellaneous Support Files" < $< > $@
support.texi: support.t
$(BMENU2) -p "Ada95 Interrupt Support Version Requirements" \
-u "Top" \
-n "" < $< > $@
init.texi: init.t
$(BMENU2) -p "" \
-u "Top" \
-n "" < $< > $@
console.texi: console.t
$(BMENU2) -p "" \
-u "Top" \
-n "" < $< > $@
clock.texi: clock.t
$(BMENU2) -p "" \
-u "Top" \
-n "" < $< > $@
timer.texi: timer.t
$(BMENU2) -p "" \
-u "Top" \
-n "" < $< > $@
rtc.texi: rtc.t
$(BMENU2) -p "" \
-u "Top" \
-n "" < $< > $@
ata.texi: ata.t
$(BMENU2) -p "" \
-u "Top" \
-n "" < $< > $@
ide-ctrl.texi: ide-ctrl.t
$(BMENU2) -p "" \
-u "Top" \
-n "" < $< > $@
nvmem.texi: nvmem.t
$(BMENU2) -p "" \
-u "Top" \
-n "" < $< > $@
#
# Grab the chapter on writing a network device driver.
#
network.texi: ../networking/driver.t
$(BMENU2) -p "" \
-u "Top" \
-n "" < $< > $@
shmsupp.texi: shmsupp.t
$(BMENU2) -p "" \
-u "Top" \
-n "" < $< > $@
framebuffer.texi: framebuffer.t
$(BMENU2) -p "" \
-u "Top" \
-n "" < $< > $@
analog.texi: analog.t
$(BMENU2) -p "" \
-u "Top" \
-n "" < $< > $@
discrete.texi: discrete.t
$(BMENU2) -p "" \
-u "Top" \
-n "" < $< > $@
CLEANFILES += bsp_howto.info bsp_howto.info-?
EXTRA_DIST = adaintr.t analog.t ata.t clock.t console.t discrete.t \
ide-ctrl.t init.t intro.t linkcmds.t makefiles.t nvmem.t rtc.t shmsupp.t \
support.t target.t timer.t $(PNG_FILES) $(EPS_IMAGES)

Some files were not shown because too many files have changed in this diff Show More