arch-generic: Fix reading from special :semihosting-features file (#1089)

The implementation of SYS_FLEN was missing, which caused picolibc to
treat this file as not implemented. Additionally, there was a bug in the
SYS_READ call that was comparing the wrong variable against the passed
buffer length. It was comparing the current file position against the
buffer length instead of the number of written bytes. Finally, pos was
unititialized which could result in spurious errors.

Change-Id: I8b487a79df5970a5001d3fef08d5579bb4aa0dd0
This commit is contained in:
Giacomo Travaglini
2024-05-06 07:30:13 +01:00
committed by GitHub
2 changed files with 12 additions and 5 deletions

View File

@@ -94,7 +94,7 @@ const std::map<uint64_t, const char *> BaseSemihosting::exitCodes{
{0x20029, "semi:ADP_Stopped_DivisionByZero"},
};
const std::vector<uint8_t> BaseSemihosting::features{
const std::array<uint8_t, 5> BaseSemihosting::features{
0x53, 0x48, 0x46, 0x42, // Magic
0x3, // EXT_EXIT_EXTENDED, EXT_STDOUT_STDERR
};
@@ -655,13 +655,19 @@ FileFeatures(BaseSemihosting &_parent, const char *_name, const char *_mode) :
FileBase(_parent, _name, _mode)
{}
int64_t
BaseSemihosting::FileFeatures::flen()
{
return features.size();
}
int64_t
BaseSemihosting::FileFeatures::read(uint8_t *buffer, uint64_t size)
{
int64_t len = 0;
for (; pos < size && pos < BaseSemihosting::features.size(); pos++)
buffer[len++] = BaseSemihosting::features[pos];
for (; len < size && pos < features.size(); pos++)
buffer[len++] = features[pos];
return len;
}

View File

@@ -323,9 +323,10 @@ class BaseSemihosting : public SimObject
int64_t read(uint8_t *buffer, uint64_t size) override;
int64_t seek(uint64_t pos) override;
int64_t flen() override;
protected:
size_t pos;
size_t pos = 0;
};
class File : public FileBase
@@ -540,7 +541,7 @@ class BaseSemihosting : public SimObject
static const std::vector<const char *> fmodes;
static const std::map<uint64_t, const char *> exitCodes;
static const std::vector<uint8_t> features;
static const std::array<uint8_t, 5> features;
static const std::map<const std::string, FILE *> stdioMap;
// used in callTmpNam() to deterministically generate a temp filename